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"
 
 
32
from bzrlib.osutils import format_date
 
 
33
from bzrlib.tests import TestSkipped
 
 
34
from bzrlib.tests.blackbox import ExternalBase
 
 
37
class TestInfo(ExternalBase):
 
41
39
    def test_info_non_existing(self):
 
42
 
        self.vfs_transport_factory = memory.MemoryServer
 
43
 
        location = self.get_url()
 
 
40
        if sys.platform == "win32":
 
 
41
            location = "C:/i/do/not/exist/"
 
 
43
            location = "/i/do/not/exist/"
 
44
44
        out, err = self.run_bzr('info '+location, retcode=3)
 
45
45
        self.assertEqual(out, '')
 
46
46
        self.assertEqual(err, 'bzr: ERROR: Not a branch: "%s".\n' % location)
 
 
63
63
        self.assertEqual('', err)
 
65
 
        # Standalone branch - verbose mode
 
66
65
        out, err = self.run_bzr('info standalone -v')
 
67
66
        self.assertEqualDiff(
 
68
67
"""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
95
        self.assertEqual('', err)
 
127
96
        tree1.commit('commit one')
 
128
97
        rev = branch1.repository.get_revision(branch1.revision_history()[0])
 
129
 
        datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
 
 
98
        datestring_first = format_date(rev.timestamp, rev.timezone)
 
131
100
        # Branch standalone with push location
 
132
101
        branch2 = branch1.bzrdir.sprout('branch').open_branch()
 
 
176
146
   first revision: %s
 
177
147
  latest revision: %s
 
181
152
""" % (datestring_first, datestring_first,
 
 
153
       # poking at _revision_store isn't all that clean, but neither is
 
 
154
       # having the ui test dependent on the exact overhead of a given store.
 
 
155
       branch2.repository._revision_store.total_size(
 
 
156
        branch2.repository.get_transaction())[1] / 1024,
 
183
158
        self.assertEqual('', err)
 
 
186
161
        # (creates backup as unknown)
 
187
162
        branch1.bzrdir.sprout('bound')
 
188
163
        knit1_format = bzrdir.format_registry.make_bzrdir('knit')
 
189
 
        upgrade.upgrade('bound', knit1_format)
 
190
 
        branch3 = bzrdir.BzrDir.open('bound').open_branch()
 
 
164
        bzrlib.upgrade.upgrade('bound', knit1_format)
 
 
165
        branch3 = bzrlib.bzrdir.BzrDir.open('bound').open_branch()
 
191
166
        branch3.bind(branch1)
 
192
167
        bound_tree = branch3.bzrdir.open_workingtree()
 
193
168
        out, err = self.run_bzr('info -v bound')
 
 
217
192
         0 versioned subdirectories
 
222
198
   first revision: %s
 
223
199
  latest revision: %s
 
227
204
""" % (bound_tree._format.get_format_description(),
 
228
205
       branch3._format.get_format_description(),
 
229
206
       branch3.repository._format.get_format_description(),
 
230
207
       datestring_first, datestring_first,
 
 
208
       # poking at _revision_store isn't all that clean, but neither is
 
 
209
       # having the ui test dependent on the exact overhead of a given store.
 
 
210
       branch3.repository._revision_store.total_size(
 
 
211
        branch3.repository.get_transaction())[1] / 1024,
 
232
213
        self.assertEqual('', err)
 
234
215
        # Checkout standalone (same as above, but does not have parent set)
 
235
 
        branch4 = bzrdir.BzrDir.create_branch_convenience('checkout',
 
 
216
        branch4 = bzrlib.bzrdir.BzrDir.create_branch_convenience('checkout',
 
236
217
            format=knit1_format)
 
237
218
        branch4.bind(branch1)
 
238
219
        branch4.bzrdir.open_workingtree().update()
 
 
265
247
   first revision: %s
 
266
248
  latest revision: %s
 
270
253
""" % (branch4.repository._format.get_format_description(),
 
271
254
       datestring_first, datestring_first,
 
 
255
       # poking at _revision_store isn't all that clean, but neither is
 
 
256
       # having the ui test dependent on the exact overhead of a given store.
 
 
257
       branch4.repository._revision_store.total_size(
 
 
258
        branch4.repository.get_transaction())[1] / 1024,
 
273
260
        self.assertEqual('', err)
 
 
277
264
        branch5 = tree5.branch
 
278
265
        out, err = self.run_bzr('info -v lightcheckout')
 
279
266
        self.assertEqualDiff(
 
280
 
"""Lightweight checkout (format: %s)
 
 
267
"""Lightweight checkout (format: dirstate or dirstate-tags or \
 
 
268
pack-0.92 or rich-root or rich-root-pack)
 
282
270
  light checkout root: lightcheckout
 
283
271
   checkout of branch: standalone
 
286
274
       control: Meta directory format 1
 
287
 
  working tree: Working tree format 6
 
 
275
  working tree: Working tree format 4
 
288
276
        branch: Branch format 4
 
289
277
    repository: Weave repository format 6
 
 
304
293
   first revision: %s
 
305
294
  latest revision: %s
 
309
 
""" % (self._repo_strings, datestring_first, datestring_first,), out)
 
 
299
""" % (datestring_first, datestring_first,), out)
 
310
300
        self.assertEqual('', err)
 
312
302
        # Update initial standalone branch
 
 
315
305
        tree1.commit('commit two')
 
316
306
        rev = branch1.repository.get_revision(branch1.revision_history()[-1])
 
317
 
        datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
 
 
307
        datestring_last = format_date(rev.timestamp, rev.timezone)
 
319
309
        # Out of date branched standalone branch will not be detected
 
320
310
        out, err = self.run_bzr('info -v branch')
 
 
385
377
         0 versioned subdirectories
 
390
383
   first revision: %s
 
391
384
  latest revision: %s
 
395
389
""" % (branch3.repository._format.get_format_description(),
 
396
390
       datestring_first, datestring_first,
 
 
391
       # poking at _revision_store isn't all that clean, but neither is
 
 
392
       # having the ui test dependent on the exact overhead of a given store.
 
 
393
       branch3.repository._revision_store.total_size(
 
 
394
        branch3.repository.get_transaction())[1] / 1024,
 
398
396
        self.assertEqual('', err)
 
 
429
428
   first revision: %s
 
430
429
  latest revision: %s
 
434
434
""" % (branch4.repository._format.get_format_description(),
 
435
435
       datestring_first, datestring_first,
 
 
436
       # poking at _revision_store isn't all that clean, but neither is
 
 
437
       # having the ui test dependent on the exact overhead of a given store.
 
 
438
       branch4.repository._revision_store.total_size(
 
 
439
        branch4.repository.get_transaction())[1] / 1024,
 
437
441
        self.assertEqual('', err)
 
439
443
        # Out of date lightweight checkout
 
440
444
        out, err = self.run_bzr('info lightcheckout --verbose')
 
441
445
        self.assertEqualDiff(
 
442
 
"""Lightweight checkout (format: %s)
 
 
446
"""Lightweight checkout (format: dirstate or dirstate-tags or \
 
 
447
pack-0.92 or rich-root or rich-root-pack)
 
444
449
  light checkout root: lightcheckout
 
445
450
   checkout of branch: standalone
 
448
453
       control: Meta directory format 1
 
449
 
  working tree: Working tree format 6
 
 
454
  working tree: Working tree format 4
 
450
455
        branch: Branch format 4
 
451
456
    repository: Weave repository format 6
 
 
468
474
   first revision: %s
 
469
475
  latest revision: %s
 
473
 
""" % (self._repo_strings, datestring_first, datestring_last,), out)
 
 
480
""" % (datestring_first, datestring_last,), out)
 
474
481
        self.assertEqual('', err)
 
476
483
    def test_info_standalone_no_tree(self):
 
 
497
506
""" % (info.describe_format(repo.bzrdir, repo, branch, None),
 
498
507
       format.get_branch_format().get_format_description(),
 
499
508
       format.repository_format.get_format_description(),
 
 
552
564
        # Create lightweight checkout
 
553
565
        transport.mkdir('tree')
 
554
566
        transport.mkdir('tree/lightcheckout')
 
555
 
        tree2 = branch1.create_checkout('tree/lightcheckout',
 
 
567
        tree2 = branch1.create_checkout('tree/lightcheckout', 
 
556
568
            lightweight=True)
 
557
569
        branch2 = tree2.branch
 
558
570
        self.assertCheckoutStatusOutput('-v tree/lightcheckout', tree2,
 
 
569
581
        tree2.commit('commit one')
 
570
582
        rev = repo.get_revision(branch2.revision_history()[0])
 
571
 
        datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
 
 
583
        datestring_first = format_date(rev.timestamp, rev.timezone)
 
572
584
        out, err = self.run_bzr('info tree/lightcheckout --verbose')
 
573
585
        self.assertEqualDiff(
 
574
 
"""Lightweight checkout (format: %s)
 
 
586
"""Lightweight checkout (format: dirstate or dirstate-tags or \
 
 
587
pack-0.92 or rich-root or rich-root-pack)
 
576
589
  light checkout root: tree/lightcheckout
 
577
590
   checkout of branch: repo/branch
 
 
599
613
   first revision: %s
 
600
614
  latest revision: %s
 
604
 
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
 
 
619
""" % (format.get_branch_format().get_format_description(),
 
605
620
       format.repository_format.get_format_description(),
 
606
621
       datestring_first, datestring_first,
 
 
622
       # poking at _revision_store isn't all that clean, but neither is
 
 
623
       # having the ui test dependent on the exact overhead of a given store.
 
 
624
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
608
626
        self.assertEqual('', err)
 
610
628
        # Out of date checkout
 
611
629
        out, err = self.run_bzr('info -v tree/checkout')
 
612
630
        self.assertEqualDiff(
 
613
 
"""Checkout (format: unnamed)
 
 
631
"""Checkout (format: dirstate)
 
615
633
       checkout root: tree/checkout
 
616
634
  checkout of branch: repo/branch
 
619
637
       control: Meta directory format 1
 
620
 
  working tree: Working tree format 6
 
 
638
  working tree: Working tree format 4
 
 
650
670
        out, err = self.run_bzr('info tree/checkout --verbose')
 
651
671
        self.assertEqualDiff(
 
652
 
"""Checkout (format: unnamed)
 
 
672
"""Checkout (format: dirstate)
 
654
674
       checkout root: tree/checkout
 
655
675
  checkout of branch: repo/branch
 
658
678
       control: Meta directory format 1
 
659
 
  working tree: Working tree format 6
 
 
679
  working tree: Working tree format 4
 
 
676
697
   first revision: %s
 
677
698
  latest revision: %s
 
681
703
""" % (format.get_branch_format().get_format_description(),
 
682
704
       format.repository_format.get_format_description(),
 
683
705
       datestring_first, datestring_first,
 
 
706
       # poking at _revision_store isn't all that clean, but neither is
 
 
707
       # having the ui test dependent on the exact overhead of a given store.
 
 
708
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
685
710
        self.assertEqual('', err)
 
686
711
        tree3.commit('commit two')
 
688
713
        # Out of date lightweight checkout
 
689
714
        rev = repo.get_revision(branch1.revision_history()[-1])
 
690
 
        datestring_last = osutils.format_date(rev.timestamp, rev.timezone)
 
 
715
        datestring_last = format_date(rev.timestamp, rev.timezone)
 
691
716
        out, err = self.run_bzr('info tree/lightcheckout --verbose')
 
692
717
        self.assertEqualDiff(
 
693
 
"""Lightweight checkout (format: %s)
 
 
718
"""Lightweight checkout (format: dirstate or dirstate-tags or \
 
 
719
pack-0.92 or rich-root or rich-root-pack)
 
695
721
  light checkout root: tree/lightcheckout
 
696
722
   checkout of branch: repo/branch
 
 
720
747
   first revision: %s
 
721
748
  latest revision: %s
 
725
 
""" % (self._repo_strings, format.get_branch_format().get_format_description(),
 
 
753
""" % (format.get_branch_format().get_format_description(),
 
726
754
       format.repository_format.get_format_description(),
 
727
755
       datestring_first, datestring_last,
 
 
756
       # poking at _revision_store isn't all that clean, but neither is
 
 
757
       # having the ui test dependent on the exact overhead of a given store.
 
 
758
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
729
760
        self.assertEqual('', err)
 
 
747
779
   first revision: %s
 
748
780
  latest revision: %s
 
752
785
""" % (format.get_branch_format().get_format_description(),
 
753
786
       format.repository_format.get_format_description(),
 
754
787
       datestring_first, datestring_last,
 
 
788
       # poking at _revision_store isn't all that clean, but neither is
 
 
789
       # having the ui test dependent on the exact overhead of a given store.
 
 
790
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
756
792
        self.assertEqual('', err)
 
 
771
808
""" % (format.repository_format.get_format_description(),
 
 
809
       # poking at _revision_store isn't all that clean, but neither is
 
 
810
       # having the ui test dependent on the exact overhead of a given store.
 
 
811
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
773
813
        self.assertEqual('', err)
 
 
844
887
        tree1.commit('commit one')
 
845
888
        rev = repo.get_revision(branch1.revision_history()[0])
 
846
 
        datestring_first = osutils.format_date(rev.timestamp, rev.timezone)
 
 
889
        datestring_first = format_date(rev.timestamp, rev.timezone)
 
847
890
        out, err = self.run_bzr('info -v repo/branch1')
 
848
891
        self.assertEqualDiff(
 
849
892
"""Repository tree (format: knit)
 
 
873
917
   first revision: %s
 
874
918
  latest revision: %s
 
878
923
""" % (format.get_branch_format().get_format_description(),
 
879
924
       format.repository_format.get_format_description(),
 
880
925
       datestring_first, datestring_first,
 
 
926
       # poking at _revision_store isn't all that clean, but neither is
 
 
927
       # having the ui test dependent on the exact overhead of a given store.
 
 
928
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
882
930
        self.assertEqual('', err)
 
 
916
966
""" % (format.get_branch_format().get_format_description(),
 
917
967
       format.repository_format.get_format_description(),
 
 
968
       # poking at _revision_store isn't all that clean, but neither is
 
 
969
       # having the ui test dependent on the exact overhead of a given store.
 
 
970
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
919
972
        self.assertEqual('', err)
 
 
953
1007
   first revision: %s
 
954
1008
  latest revision: %s
 
958
1013
""" % (format.get_branch_format().get_format_description(),
 
959
1014
       format.repository_format.get_format_description(),
 
960
1015
       datestring_first, datestring_first,
 
 
1016
       # poking at _revision_store isn't all that clean, but neither is
 
 
1017
       # having the ui test dependent on the exact overhead of a given store.
 
 
1018
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
962
1020
        self.assertEqual('', err)
 
 
979
1038
""" % (format.repository_format.get_format_description(),
 
 
1039
       # poking at _revision_store isn't all that clean, but neither is
 
 
1040
       # having the ui test dependent on the exact overhead of a given store.
 
 
1041
       repo._revision_store.total_size(repo.get_transaction())[1] / 1024,
 
982
1044
        self.assertEqual('', err)
 
984
1046
    def test_info_shared_repository_with_tree_in_root(self):
 
985
1047
        format = bzrdir.format_registry.make_bzrdir('knit')
 
986
1048
        transport = self.get_transport()
 
 
1036
1099
Branch history:
 
1041
1106
""" % (format.get_branch_format().get_format_description(),
 
1042
1107
       format.repository_format.get_format_description(),
 
1044
1109
        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
1111
    def assertCheckoutStatusOutput(self,
 
1073
1112
        command_string, lco_tree, shared_repo=None,
 
1074
1113
        repo_branch=None,
 
 
1084
1123
        allow us, the test writers, to document what *should* be present in
 
1085
1124
        the output. Removing this separation would remove the value of the
 
1088
1127
        :param path: the path to the light checkout.
 
1089
1128
        :param lco_tree: the tree object for the light checkout.
 
1090
1129
        :param shared_repo: A shared repository is in use, expect that in
 
 
1098
1137
            actually locked then this parameter is overridden. This is because
 
1099
1138
            pack repositories do not have any public API for obtaining an
 
1100
1139
            exclusive repository wide lock.
 
1101
 
        :param verbose: verbosity level: 2 or higher to show committers
 
 
1140
        :param verbose: If true, expect verbose output
 
1103
1142
        def friendly_location(url):
 
1104
1143
            path = urlutils.unescape_for_display(url, 'ascii')
 
 
1123
1162
            (False, True): 'Lightweight checkout',
 
1124
1163
            (False, False): 'Checkout',
 
1125
1164
            }[(shared_repo is not None, light_checkout)]
 
1126
 
        format = {True: self._repo_strings,
 
1127
 
                  False: 'unnamed'}[light_checkout]
 
 
1165
        format = {True: 'dirstate or dirstate-tags or pack-0.92'
 
 
1166
                        ' or rich-root or rich-root-pack',
 
 
1167
                  False: 'dirstate'}[light_checkout]
 
1128
1168
        if repo_locked:
 
1129
1169
            repo_locked = lco_tree.branch.repository.get_physical_lock_status()
 
1130
1170
        if repo_locked or branch_locked or tree_locked:
 
 
1214
1255
        transport = self.get_transport()
 
1215
1256
        # Create shared repository with a branch
 
1216
1257
        repo = self.make_repository('repo', shared=True,
 
1217
 
                                    format=bzrdir.BzrDirMetaFormat1())
 
 
1258
                                    format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1218
1259
        repo.set_make_working_trees(False)
 
1219
1260
        repo.bzrdir.root_transport.mkdir('branch')
 
1220
1261
        repo_branch = repo.bzrdir.create_branch_convenience('repo/branch',
 
1221
 
                                    format=bzrdir.BzrDirMetaFormat1())
 
 
1262
                                    format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1222
1263
        # Do a heavy checkout
 
1223
1264
        transport.mkdir('tree')
 
1224
1265
        transport.mkdir('tree/checkout')
 
1225
 
        co_branch = bzrdir.BzrDir.create_branch_convenience('tree/checkout',
 
1226
 
            format=bzrdir.BzrDirMetaFormat1())
 
 
1266
        co_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience('tree/checkout',
 
 
1267
            format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1227
1268
        co_branch.bind(repo_branch)
 
1228
1269
        # Do a light checkout of the heavy one
 
1229
1270
        transport.mkdir('tree/lightcheckout')
 
1230
 
        lco_dir = bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
 
1231
 
        branch.BranchReferenceFormat().initialize(lco_dir,
 
1232
 
            target_branch=co_branch)
 
 
1271
        lco_dir = bzrlib.bzrdir.BzrDirMetaFormat1().initialize('tree/lightcheckout')
 
 
1272
        bzrlib.branch.BranchReferenceFormat().initialize(lco_dir, co_branch)
 
1233
1273
        lco_dir.create_workingtree()
 
1234
1274
        lco_tree = lco_dir.open_workingtree()
 
 
1326
1366
    def test_info_locking_oslocks(self):
 
1327
1367
        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()
 
 
1368
            raise TestSkipped("don't use oslocks on win32 in unix manner")
 
1335
1370
        tree = self.make_branch_and_tree('branch',
 
1336
 
                                         format=bzrdir.BzrDirFormat6())
 
 
1371
                                         format=bzrlib.bzrdir.BzrDirFormat6())
 
1338
1373
        # Test all permutations of locking the working tree, branch and repository
 
1339
1374
        # XXX: Well not yet, as we can't query oslocks yet. Currently, it's
 
 
1399
1436
Branch history:
 
1404
1443
""" % ('branch', tree.branch.repository._format.get_format_description(),
 
1406
1445
        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)