1
# Copyright (C) 2006, 2007 Canonical Ltd
1
# Copyright (C) 2006, 2007, 2008 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
31
from bzrlib.osutils import format_date
35
36
class TestInfo(ExternalBase):
39
ExternalBase.setUp(self)
40
self._repo_strings = "2a or development-subtree"
37
42
def test_info_non_existing(self):
38
43
if sys.platform == "win32":
39
44
location = "C:/i/do/not/exist/"
61
66
self.assertEqual('', err)
68
# Standalone branch - verbose mode
63
69
out, err = self.run_bzr('info standalone -v')
64
70
self.assertEqualDiff(
65
71
"""Standalone tree (format: weave)
97
self.assertEqual('', err)
99
# Standalone branch - really verbose mode
100
out, err = self.run_bzr('info standalone -vv')
101
self.assertEqualDiff(
102
"""Standalone tree (format: weave)
104
branch root: standalone
107
control: All-in-one format 6
108
working tree: Working tree format 2
109
branch: Branch format 4
110
repository: Weave repository format 6
120
0 versioned subdirectories
93
129
self.assertEqual('', err)
94
130
tree1.commit('commit one')
144
179
first revision: %s
145
180
latest revision: %s
150
184
""" % (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
186
self.assertEqual('', err)
159
189
# (creates backup as unknown)
160
190
branch1.bzrdir.sprout('bound')
161
191
knit1_format = bzrdir.format_registry.make_bzrdir('knit')
162
bzrlib.upgrade.upgrade('bound', knit1_format)
163
branch3 = bzrlib.bzrdir.BzrDir.open('bound').open_branch()
192
upgrade.upgrade('bound', knit1_format)
193
branch3 = bzrdir.BzrDir.open('bound').open_branch()
164
194
branch3.bind(branch1)
165
195
bound_tree = branch3.bzrdir.open_workingtree()
166
196
out, err = self.run_bzr('info -v bound')
196
225
first revision: %s
197
226
latest revision: %s
202
230
""" % (bound_tree._format.get_format_description(),
203
231
branch3._format.get_format_description(),
204
232
branch3.repository._format.get_format_description(),
205
233
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
235
self.assertEqual('', err)
213
237
# Checkout standalone (same as above, but does not have parent set)
214
branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
238
branch4 = bzrdir.BzrDir.create_branch_convenience('checkout',
215
239
format=knit1_format)
216
240
branch4.bind(branch1)
217
241
branch4.bzrdir.open_workingtree().update()
245
268
first revision: %s
246
269
latest revision: %s
251
273
""" % (branch4.repository._format.get_format_description(),
252
274
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
276
self.assertEqual('', err)
262
280
branch5 = tree5.branch
263
281
out, err = self.run_bzr('info -v lightcheckout')
264
282
self.assertEqualDiff(
265
"""Lightweight checkout (format: dirstate or dirstate-tags)
283
"""Lightweight checkout (format: %s)
267
285
light checkout root: lightcheckout
268
286
checkout of branch: standalone
271
289
control: Meta directory format 1
272
working tree: Working tree format 4
290
working tree: Working tree format 6
273
291
branch: Branch format 4
274
292
repository: Weave repository format 6
290
307
first revision: %s
291
308
latest revision: %s
296
""" % (datestring_first, datestring_first,), out)
312
""" % (self._repo_strings, datestring_first, datestring_first,), out)
297
313
self.assertEqual('', err)
299
315
# Update initial standalone branch
380
393
first revision: %s
381
394
latest revision: %s
386
398
""" % (branch3.repository._format.get_format_description(),
387
399
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
401
self.assertEqual('', err)
425
432
first revision: %s
426
433
latest revision: %s
431
437
""" % (branch4.repository._format.get_format_description(),
432
438
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
440
self.assertEqual('', err)
440
442
# Out of date lightweight checkout
441
443
out, err = self.run_bzr('info lightcheckout --verbose')
442
444
self.assertEqualDiff(
443
"""Lightweight checkout (format: dirstate or dirstate-tags)
445
"""Lightweight checkout (format: %s)
445
447
light checkout root: lightcheckout
446
448
checkout of branch: standalone
449
451
control: Meta directory format 1
450
working tree: Working tree format 4
452
working tree: Working tree format 6
451
453
branch: Branch format 4
452
454
repository: Weave repository format 6
470
471
first revision: %s
471
472
latest revision: %s
476
""" % (datestring_first, datestring_last,), out)
476
""" % (self._repo_strings, datestring_first, datestring_last,), out)
477
477
self.assertEqual('', err)
479
479
def test_info_standalone_no_tree(self):
502
""" % (format.get_branch_format().get_format_description(),
500
""" % (info.describe_format(repo.bzrdir, repo, branch, None),
501
format.get_branch_format().get_format_description(),
503
502
format.repository_format.get_format_description(),
505
504
self.assertEqual('', err)
559
555
# Create lightweight checkout
560
556
transport.mkdir('tree')
561
557
transport.mkdir('tree/lightcheckout')
562
tree2 = branch1.create_checkout('tree/lightcheckout',
558
tree2 = branch1.create_checkout('tree/lightcheckout',
563
559
lightweight=True)
564
560
branch2 = tree2.branch
565
561
self.assertCheckoutStatusOutput('-v tree/lightcheckout', tree2,
578
574
datestring_first = format_date(rev.timestamp, rev.timezone)
579
575
out, err = self.run_bzr('info tree/lightcheckout --verbose')
580
576
self.assertEqualDiff(
581
"""Lightweight checkout (format: dirstate or dirstate-tags)
577
"""Lightweight checkout (format: %s)
583
579
light checkout root: tree/lightcheckout
584
580
checkout of branch: repo/branch
607
602
first revision: %s
608
603
latest revision: %s
613
""" % (format.get_branch_format().get_format_description(),
607
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
614
608
format.repository_format.get_format_description(),
615
609
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
611
self.assertEqual('', err)
622
613
# Out of date checkout
623
614
out, err = self.run_bzr('info -v tree/checkout')
624
615
self.assertEqualDiff(
625
"""Checkout (format: dirstate)
616
"""Checkout (format: unnamed)
627
618
checkout root: tree/checkout
628
619
checkout of branch: repo/branch
631
622
control: Meta directory format 1
632
working tree: Working tree format 4
623
working tree: Working tree format 6
664
653
out, err = self.run_bzr('info tree/checkout --verbose')
665
654
self.assertEqualDiff(
666
"""Checkout (format: dirstate)
655
"""Checkout (format: unnamed)
668
657
checkout root: tree/checkout
669
658
checkout of branch: repo/branch
672
661
control: Meta directory format 1
673
working tree: Working tree format 4
662
working tree: Working tree format 6
691
679
first revision: %s
692
680
latest revision: %s
697
684
""" % (format.get_branch_format().get_format_description(),
698
685
format.repository_format.get_format_description(),
699
686
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
688
self.assertEqual('', err)
705
689
tree3.commit('commit two')
709
693
datestring_last = format_date(rev.timestamp, rev.timezone)
710
694
out, err = self.run_bzr('info tree/lightcheckout --verbose')
711
695
self.assertEqualDiff(
712
"""Lightweight checkout (format: dirstate or dirstate-tags)
696
"""Lightweight checkout (format: %s)
714
698
light checkout root: tree/lightcheckout
715
699
checkout of branch: repo/branch
740
723
first revision: %s
741
724
latest revision: %s
746
""" % (format.get_branch_format().get_format_description(),
728
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
747
729
format.repository_format.get_format_description(),
748
730
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
732
self.assertEqual('', err)
772
750
first revision: %s
773
751
latest revision: %s
778
755
""" % (format.get_branch_format().get_format_description(),
779
756
format.repository_format.get_format_description(),
780
757
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
759
self.assertEqual('', err)
801
774
""" % (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
776
self.assertEqual('', err)
910
876
first revision: %s
911
877
latest revision: %s
916
881
""" % (format.get_branch_format().get_format_description(),
917
882
format.repository_format.get_format_description(),
918
883
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
885
self.assertEqual('', err)
959
919
""" % (format.get_branch_format().get_format_description(),
960
920
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
922
self.assertEqual('', err)
1000
956
first revision: %s
1001
957
latest revision: %s
1006
961
""" % (format.get_branch_format().get_format_description(),
1007
962
format.repository_format.get_format_description(),
1008
963
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
965
self.assertEqual('', err)
1031
982
""" % (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
985
self.assertEqual('', err)
1039
987
def test_info_shared_repository_with_tree_in_root(self):
1040
988
format = bzrdir.format_registry.make_bzrdir('knit')
1041
989
transport = self.get_transport()
1092
1039
Branch history:
1099
1044
""" % (format.get_branch_format().get_format_description(),
1100
1045
format.repository_format.get_format_description(),
1102
1047
self.assertEqual('', err)
1104
def assertCheckoutStatusOutput(self,
1049
def test_info_repository_hook(self):
1050
format = bzrdir.format_registry.make_bzrdir('knit')
1051
def repo_info(repo, stats, outf):
1052
outf.write("more info\n")
1053
info.hooks.install_named_hook('repository', repo_info, None)
1054
# Create shared repository with working trees
1055
repo = self.make_repository('repo', shared=True, format=format)
1056
out, err = self.run_bzr('info -v repo')
1057
self.assertEqualDiff(
1058
"""Shared repository with trees (format: dirstate or dirstate-tags or knit)
1060
shared repository: repo
1063
control: Meta directory format 1
1066
Create working tree for new branches inside the repository.
1071
""" % (format.repository_format.get_format_description(),
1073
self.assertEqual('', err)
1075
def assertCheckoutStatusOutput(self,
1105
1076
command_string, lco_tree, shared_repo=None,
1106
1077
repo_branch=None,
1107
1078
tree_locked=False,
1116
1087
allow us, the test writers, to document what *should* be present in
1117
1088
the output. Removing this separation would remove the value of the
1120
1091
:param path: the path to the light checkout.
1121
1092
:param lco_tree: the tree object for the light checkout.
1122
1093
:param shared_repo: A shared repository is in use, expect that in
1126
1097
:param tree_locked: If true, expect the tree to be locked.
1127
1098
:param branch_locked: If true, expect the branch to be locked.
1128
1099
:param repo_locked: If true, expect the repository to be locked.
1129
:param verbose: If true, expect verbose output
1100
Note that the lco_tree.branch.repository is inspected, and if is not
1101
actually locked then this parameter is overridden. This is because
1102
pack repositories do not have any public API for obtaining an
1103
exclusive repository wide lock.
1104
:param verbose: verbosity level: 2 or higher to show committers
1131
1106
def friendly_location(url):
1132
1107
path = urlutils.unescape_for_display(url, 'ascii')
1134
return osutils.relpath(os.getcwd(), path)
1109
return osutils.relpath(osutils.getcwd(), path)
1135
1110
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).
1114
# We expect this to fail because of locking errors.
1115
# (A write-locked file cannot be read-locked
1116
# in the different process -- either on win32 or on linux).
1141
1117
# This should be removed when the locking errors are fixed.
1142
args = command_string.split(' ')
1143
self.run_bzr_error([], 'info', *args)
1118
self.expectFailure('OS locks are exclusive '
1119
'for different processes (Bug #174055)',
1120
self.run_bzr_subprocess,
1121
'info ' + command_string)
1145
1122
out, err = self.run_bzr('info %s' % command_string)
1146
1123
description = {
1147
1124
(True, True): 'Lightweight checkout',
1149
1126
(False, True): 'Lightweight checkout',
1150
1127
(False, False): 'Checkout',
1151
1128
}[(shared_repo is not None, light_checkout)]
1152
format = {True: 'dirstate or dirstate-tags',
1153
False: 'dirstate'}[light_checkout]
1129
format = {True: self._repo_strings,
1130
False: 'unnamed'}[light_checkout]
1132
repo_locked = lco_tree.branch.repository.get_physical_lock_status()
1154
1133
if repo_locked or branch_locked or tree_locked:
1155
1134
def locked_message(a_bool):
1239
1217
transport = self.get_transport()
1240
1218
# Create shared repository with a branch
1241
1219
repo = self.make_repository('repo', shared=True,
1242
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1220
format=bzrdir.BzrDirMetaFormat1())
1243
1221
repo.set_make_working_trees(False)
1244
1222
repo.bzrdir.root_transport.mkdir('branch')
1245
1223
repo_branch = repo.bzrdir.create_branch_convenience('repo/branch',
1246
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1224
format=bzrdir.BzrDirMetaFormat1())
1247
1225
# Do a heavy checkout
1248
1226
transport.mkdir('tree')
1249
1227
transport.mkdir('tree/checkout')
1250
co_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1251
format=bzrlib.bzrdir.BzrDirMetaFormat1())
1228
co_branch = bzrdir.BzrDir.create_branch_convenience('tree/checkout',
1229
format=bzrdir.BzrDirMetaFormat1())
1252
1230
co_branch.bind(repo_branch)
1253
1231
# Do a light checkout of the heavy one
1254
1232
transport.mkdir('tree/lightcheckout')
1255
lco_dir = bzrlib.bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1256
bzrlib.branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1233
lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
1234
branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
1257
1235
lco_dir.create_workingtree()
1258
1236
lco_tree = lco_dir.open_workingtree()
1350
1328
def test_info_locking_oslocks(self):
1351
1329
if sys.platform == "win32":
1352
1330
raise TestSkipped("don't use oslocks on win32 in unix manner")
1331
self.thisFailsStrictLockCheck()
1354
1333
tree = self.make_branch_and_tree('branch',
1355
format=bzrlib.bzrdir.BzrDirFormat6())
1334
format=bzrdir.BzrDirFormat6())
1357
1336
# Test all permutations of locking the working tree, branch and repository
1358
1337
# XXX: Well not yet, as we can't query oslocks yet. Currently, it's
1420
1397
Branch history:
1427
1402
""" % ('branch', tree.branch.repository._format.get_format_description(),
1429
1404
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)