~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/bzrdir_implementations/test_bzrdir.py

Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tests for bzrdir implementations - tests a bzrdir format."""
18
18
 
19
19
import os
 
20
from stat import *
20
21
import sys
21
22
 
22
23
import bzrlib.branch as branch
68
69
 
69
70
 
70
71
class TestBzrDir(TestCaseWithBzrDir):
71
 
 
72
 
    def test_clone_bzrdir(self):
73
 
        #TODO: Test that we can create a clone of a bzr dir 
74
 
        #
75
 
        #... and all its contents verbatim.
76
 
        raise AssertionError('not tested yet.')
77
 
 
78
 
        # a bunch of tests needed::
79
 
        # create a bzr dir with nothing, clone it check result has nothing
80
 
        # create a bzr dir with storage only, clone it check result has same
81
 
        # storage contents
82
 
        # create bzr dir with branch with no storage, clone, check resulting
83
 
        # dir also has no storage but does have branch
84
 
        # create bzr dir with a tree but no storage or branch (on local disk
85
 
        # as thats how workingtree works) clone and check no branch or 
86
 
        # storage is made
87
 
        # create a standalone_branch , clone that and check all bits are
88
 
        # clone.
89
 
        # these should all check that the formats on subthings like repository
90
 
        # are the same as the source format.
91
 
        # features that are not supported (like detached working trees for
92
 
        # older formats, should catch the error and silently pass the test 
93
 
        # as they are honouring the format.
94
 
 
95
 
    def test_new_line_of_development_bzrdir(self):
96
 
        #TODO: Test that we can create a line of development from a 
97
 
        raise AssertionError('not tested yet.')
98
 
         
99
 
        # same permutations as clone_bzrdir, or nearly so, but we want to
100
 
        # have checkouts force creation of a new branch because thats the 
101
 
        # desired semantic.
 
72
    # Many of these tests test for disk equality rather than checking
 
73
    # for semantic equivalence. This works well for some tests but
 
74
    # is not good at handling changes in representation or the addition
 
75
    # or removal of control data. It would be nice to for instance:
 
76
    # sprout a new branch, check that the nickname has been reset by hand
 
77
    # and then set the nickname to match the source branch, at which point
 
78
    # a semantic equivalence should pass
 
79
 
 
80
    def assertDirectoriesEqual(self, source, target, ignore_list=[]):
 
81
        """Assert that the content of source and target are identical.
 
82
 
 
83
        paths in ignore list will be completely ignored.
 
84
        """
 
85
        files = []
 
86
        directories = ['.']
 
87
        while directories:
 
88
            dir = directories.pop()
 
89
            for path in source.list_dir(dir):
 
90
                path = dir + '/' + path
 
91
                if path in ignore_list:
 
92
                    continue
 
93
                stat = source.stat(path)
 
94
                if S_ISDIR(stat.st_mode):
 
95
                    self.assertTrue(S_ISDIR(target.stat(path).st_mode))
 
96
                    directories.append(path)
 
97
                else:
 
98
                    self.assertEqualDiff(source.get(path).read(),
 
99
                                         target.get(path).read(),
 
100
                                         "text for file %r differs:\n" % path)
 
101
 
 
102
    def test_clone_bzrdir_empty(self):
 
103
        dir = self.make_bzrdir('source')
 
104
        target = dir.clone(self.get_url('target'))
 
105
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
106
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
107
    
 
108
    def test_clone_bzrdir_repository(self):
 
109
        dir = self.make_bzrdir('source')
 
110
        repo = dir.create_repository()
 
111
        # add some content to differentiate from an empty repository.
 
112
        repo.control_weaves.add_text('inventory',
 
113
                                     "A",
 
114
                                     [],
 
115
                                     [],
 
116
                                     repo.get_transaction())
 
117
        target = dir.clone(self.get_url('target'))
 
118
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
119
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
120
 
 
121
    def test_clone_bzrdir_repository_revision(self):
 
122
        # test for revision limiting, [smoke test, not corner case checks].
 
123
        # make a repository with some revisions,
 
124
        # and clone it with a revision limit.
 
125
        # 
 
126
        tree = self.make_branch_and_tree('commit_tree')
 
127
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
128
        tree.add('foo')
 
129
        tree.commit('revision 1', rev_id='1')
 
130
        tree.bzrdir.open_branch().set_revision_history([])
 
131
        tree.set_last_revision(None)
 
132
        tree.commit('revision 2', rev_id='2')
 
133
        source = self.make_repository('source')
 
134
        tree.bzrdir.open_repository().copy_content_into(source)
 
135
        dir = source.bzrdir
 
136
        target = dir.clone(self.get_url('target'), revision_id='2')
 
137
        raise TestSkipped('revision limiting not strict yet')
 
138
 
 
139
    def test_clone_bzrdir_branch_and_repo(self):
 
140
        tree = self.make_branch_and_tree('commit_tree')
 
141
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
142
        tree.add('foo')
 
143
        tree.commit('revision 1')
 
144
        source = self.make_branch('source')
 
145
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
146
        tree.bzrdir.open_branch().copy_content_into(source)
 
147
        dir = source.bzrdir
 
148
        target = dir.clone(self.get_url('target'))
 
149
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
150
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
151
 
 
152
    def test_clone_bzrdir_branch_reference(self):
 
153
        # cloning should preserve the reference status of the branch in a bzrdir
 
154
        referenced_branch = self.make_branch('referencced')
 
155
        dir = self.make_bzrdir('source')
 
156
        try:
 
157
            reference = branch.BranchReferenceFormat().initialize(dir,
 
158
                referenced_branch)
 
159
        except errors.IncompatibleFormat:
 
160
            # this is ok too, not all formats have to support references.
 
161
            return
 
162
        target = dir.clone(self.get_url('target'))
 
163
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
164
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
165
 
 
166
    def test_clone_bzrdir_branch_revision(self):
 
167
        # test for revision limiting, [smoke test, not corner case checks].
 
168
        # make a branch with some revisions,
 
169
        # and clone it with a revision limit.
 
170
        # 
 
171
        tree = self.make_branch_and_tree('commit_tree')
 
172
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
173
        tree.add('foo')
 
174
        tree.commit('revision 1', rev_id='1')
 
175
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
176
        source = self.make_branch('source')
 
177
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
178
        tree.bzrdir.open_branch().copy_content_into(source)
 
179
        dir = source.bzrdir
 
180
        target = dir.clone(self.get_url('target'), revision_id='1')
 
181
        self.assertEqual('1', target.open_branch().last_revision())
 
182
        
 
183
    def test_clone_bzrdir_tree_branch_repo(self):
 
184
        tree = self.make_branch_and_tree('sourcce')
 
185
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
186
        tree.add('foo')
 
187
        tree.commit('revision 1')
 
188
        dir = tree.bzrdir
 
189
        target = dir.clone(self.get_url('target'))
 
190
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
191
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
192
                                    ['./.bzr/stat-cache'])
 
193
 
 
194
    def test_clone_bzrdir_tree_branch_reference(self):
 
195
        # a tree with a branch reference (aka a checkout) 
 
196
        # should stay a checkout on clone.
 
197
        referenced_branch = self.make_branch('referencced')
 
198
        dir = self.make_bzrdir('source')
 
199
        try:
 
200
            reference = branch.BranchReferenceFormat().initialize(dir,
 
201
                referenced_branch)
 
202
        except errors.IncompatibleFormat:
 
203
            # this is ok too, not all formats have to support references.
 
204
            return
 
205
        dir.create_workingtree()
 
206
        target = dir.clone(self.get_url('target'))
 
207
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
208
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
209
                                    ['./.bzr/stat-cache'])
 
210
 
 
211
    def test_clone_bzrdir_tree_revision(self):
 
212
        # test for revision limiting, [smoke test, not corner case checks].
 
213
        # make a tree with a revision with a last-revision
 
214
        # and clone it with a revision limit.
 
215
        # This smoke test just checks the revision-id is right. Tree specific
 
216
        # tests will check corner cases.
 
217
        tree = self.make_branch_and_tree('source')
 
218
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
219
        tree.add('foo')
 
220
        tree.commit('revision 1', rev_id='1')
 
221
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
222
        dir = tree.bzrdir
 
223
        target = dir.clone(self.get_url('target'), revision_id='1')
 
224
        self.assertEqual('1', target.open_workingtree().last_revision())
 
225
 
 
226
    def test_clone_bzrdir_incomplete_source_with_basis(self):
 
227
        # ensure that basis really does grab from the basis by having incomplete source
 
228
        tree = self.make_branch_and_tree('commit_tree')
 
229
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
230
        tree.add('foo')
 
231
        tree.commit('revision 1', rev_id='1')
 
232
        source = self.make_branch_and_tree('source')
 
233
        # this gives us an incomplete repository
 
234
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
235
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
236
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
237
        tree.copy_content_into(source)
 
238
        self.assertFalse(source.branch.repository.has_revision('2'))
 
239
        dir = source.bzrdir
 
240
        target = dir.clone(self.get_url('target'), basis=tree.bzrdir)
 
241
        self.assertEqual('2', target.open_branch().last_revision())
 
242
        self.assertEqual('2', target.open_workingtree().last_revision())
 
243
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
244
 
 
245
    def test_sprout_bzrdir_empty(self):
 
246
        dir = self.make_bzrdir('source')
 
247
        target = dir.sprout(self.get_url('target'))
 
248
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
249
        # creates a new repository branch and tree
 
250
        target.open_repository()
 
251
        target.open_branch()
 
252
        target.open_workingtree()
 
253
    
 
254
    def test_sprout_bzrdir_repository(self):
 
255
        dir = self.make_bzrdir('source')
 
256
        repo = dir.create_repository()
 
257
        # add some content to differentiate from an empty repository.
 
258
        repo.control_weaves.add_text('inventory',
 
259
                                     "A",
 
260
                                     [],
 
261
                                     [],
 
262
                                     repo.get_transaction())
 
263
        target = dir.sprout(self.get_url('target'))
 
264
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
265
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
266
 
 
267
    def test_sprout_bzrdir_repository_revision(self):
 
268
        # test for revision limiting, [smoke test, not corner case checks].
 
269
        # make a repository with some revisions,
 
270
        # and sprout it with a revision limit.
 
271
        # 
 
272
        tree = self.make_branch_and_tree('commit_tree')
 
273
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
274
        tree.add('foo')
 
275
        tree.commit('revision 1', rev_id='1')
 
276
        tree.bzrdir.open_branch().set_revision_history([])
 
277
        tree.set_last_revision(None)
 
278
        tree.commit('revision 2', rev_id='2')
 
279
        source = self.make_repository('source')
 
280
        tree.bzrdir.open_repository().copy_content_into(source)
 
281
        dir = source.bzrdir
 
282
        target = dir.sprout(self.get_url('target'), revision_id='2')
 
283
        raise TestSkipped('revision limiting not strict yet')
 
284
 
 
285
    def test_sprout_bzrdir_branch_and_repo(self):
 
286
        tree = self.make_branch_and_tree('commit_tree')
 
287
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
288
        tree.add('foo')
 
289
        tree.commit('revision 1')
 
290
        source = self.make_branch('source')
 
291
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
292
        tree.bzrdir.open_branch().copy_content_into(source)
 
293
        dir = source.bzrdir
 
294
        target = dir.sprout(self.get_url('target'))
 
295
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
296
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
297
 
 
298
    def test_sprout_bzrdir_branch_reference(self):
 
299
        # sprouting should create a repository if needed and a sprouted branch.
 
300
        referenced_branch = self.make_branch('referencced')
 
301
        dir = self.make_bzrdir('source')
 
302
        try:
 
303
            reference = branch.BranchReferenceFormat().initialize(dir,
 
304
                referenced_branch)
 
305
        except errors.IncompatibleFormat:
 
306
            # this is ok too, not all formats have to support references.
 
307
            return
 
308
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
309
        target = dir.sprout(self.get_url('target'))
 
310
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
311
        # we want target to have a branch that is in-place.
 
312
        self.assertEqual(target, target.open_branch().bzrdir)
 
313
        # and as we dont support repositories being detached yet, a repo in 
 
314
        # place
 
315
        target.open_repository()
 
316
 
 
317
    def test_sprout_bzrdir_branch_revision(self):
 
318
        # test for revision limiting, [smoke test, not corner case checks].
 
319
        # make a repository with some revisions,
 
320
        # and sprout it with a revision limit.
 
321
        # 
 
322
        tree = self.make_branch_and_tree('commit_tree')
 
323
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
324
        tree.add('foo')
 
325
        tree.commit('revision 1', rev_id='1')
 
326
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
327
        source = self.make_branch('source')
 
328
        tree.bzrdir.open_repository().copy_content_into(source.repository)
 
329
        tree.bzrdir.open_branch().copy_content_into(source)
 
330
        dir = source.bzrdir
 
331
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
332
        self.assertEqual('1', target.open_branch().last_revision())
 
333
        
 
334
    def test_sprout_bzrdir_tree_branch_repo(self):
 
335
        tree = self.make_branch_and_tree('sourcce')
 
336
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
 
337
        tree.add('foo')
 
338
        tree.commit('revision 1')
 
339
        dir = tree.bzrdir
 
340
        target = dir.sprout(self.get_url('target'))
 
341
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
342
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
 
343
                                    ['./.bzr/stat-cache'])
 
344
 
 
345
    def test_sprout_bzrdir_tree_branch_reference(self):
 
346
        # sprouting should create a repository if needed and a sprouted branch.
 
347
        # the tree state should be copied.
 
348
        referenced_branch = self.make_branch('referencced')
 
349
        dir = self.make_bzrdir('source')
 
350
        try:
 
351
            reference = branch.BranchReferenceFormat().initialize(dir,
 
352
                referenced_branch)
 
353
        except errors.IncompatibleFormat:
 
354
            # this is ok too, not all formats have to support references.
 
355
            return
 
356
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
357
        dir.create_workingtree()
 
358
        target = dir.sprout(self.get_url('target'))
 
359
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
360
        # we want target to have a branch that is in-place.
 
361
        self.assertEqual(target, target.open_branch().bzrdir)
 
362
        # and as we dont support repositories being detached yet, a repo in 
 
363
        # place
 
364
        target.open_repository()
 
365
        # we trust that the working tree sprouting works via the other tests.
 
366
        target.open_workingtree()
 
367
 
 
368
    def test_sprout_bzrdir_tree_branch_reference_revision(self):
 
369
        # sprouting should create a repository if needed and a sprouted branch.
 
370
        # the tree state should be copied but the revision changed,
 
371
        # and the likewise the new branch should be truncated too
 
372
        referenced_branch = self.make_branch('referencced')
 
373
        dir = self.make_bzrdir('source')
 
374
        try:
 
375
            reference = branch.BranchReferenceFormat().initialize(dir,
 
376
                referenced_branch)
 
377
        except errors.IncompatibleFormat:
 
378
            # this is ok too, not all formats have to support references.
 
379
            return
 
380
        self.assertRaises(errors.NoRepositoryPresent, dir.open_repository)
 
381
        tree = dir.create_workingtree()
 
382
        self.build_tree(['foo'], transport=dir.root_transport)
 
383
        tree.add('foo')
 
384
        tree.commit('revision 1', rev_id='1')
 
385
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
386
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
387
        self.assertNotEqual(dir.transport.base, target.transport.base)
 
388
        # we want target to have a branch that is in-place.
 
389
        self.assertEqual(target, target.open_branch().bzrdir)
 
390
        # and as we dont support repositories being detached yet, a repo in 
 
391
        # place
 
392
        target.open_repository()
 
393
        # we trust that the working tree sprouting works via the other tests.
 
394
        self.assertEqual('1', target.open_workingtree().last_revision())
 
395
        self.assertEqual('1', target.open_branch().last_revision())
 
396
 
 
397
    def test_sprout_bzrdir_tree_revision(self):
 
398
        # test for revision limiting, [smoke test, not corner case checks].
 
399
        # make a tree with a revision with a last-revision
 
400
        # and sprout it with a revision limit.
 
401
        # This smoke test just checks the revision-id is right. Tree specific
 
402
        # tests will check corner cases.
 
403
        tree = self.make_branch_and_tree('source')
 
404
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
405
        tree.add('foo')
 
406
        tree.commit('revision 1', rev_id='1')
 
407
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
408
        dir = tree.bzrdir
 
409
        target = dir.sprout(self.get_url('target'), revision_id='1')
 
410
        self.assertEqual('1', target.open_workingtree().last_revision())
 
411
 
 
412
    def test_sprout_bzrdir_incomplete_source_with_basis(self):
 
413
        # ensure that basis really does grab from the basis by having incomplete source
 
414
        tree = self.make_branch_and_tree('commit_tree')
 
415
        self.build_tree(['foo'], transport=tree.bzrdir.root_transport)
 
416
        tree.add('foo')
 
417
        tree.commit('revision 1', rev_id='1')
 
418
        source = self.make_branch_and_tree('source')
 
419
        # this gives us an incomplete repository
 
420
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
 
421
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
 
422
        tree.bzrdir.open_branch().copy_content_into(source.branch)
 
423
        tree.copy_content_into(source)
 
424
        self.assertFalse(source.branch.repository.has_revision('2'))
 
425
        dir = source.bzrdir
 
426
        target = dir.sprout(self.get_url('target'), basis=tree.bzrdir)
 
427
        self.assertEqual('2', target.open_branch().last_revision())
 
428
        self.assertEqual('2', target.open_workingtree().last_revision())
 
429
        self.assertTrue(target.open_branch().repository.has_revision('2'))
102
430
 
103
431
    def test_format_initialize_find_open(self):
104
432
        # loopback test to check the current format initializes to itself.
281
609
        self.assertTrue(isinstance(found_transport, transport.Transport))
282
610
        # and the dir which has been initialized for us must be statable.
283
611
        found_transport.stat('.')
 
612
 
 
613
    def test_root_transport(self):
 
614
        dir = self.make_bzrdir('.')
 
615
        self.assertEqual(dir.root_transport.base,
 
616
                         get_transport(self.get_url('.')).base)
 
617