~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-06-03 20:18:35 UTC
  • mfrom: (1185.82.137 w-changeset)
  • Revision ID: pqm@pqm.ubuntu.com-20060603201835-1c9a1725641ccd24
Implement bundles

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
2
 
#
 
1
# Copyright (C) 2005 by Canonical Ltd
 
2
 
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
#
 
7
 
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
#
 
12
 
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
from cStringIO import StringIO
18
18
import os
19
 
import time
20
19
 
21
 
from bzrlib import errors, inventory, osutils
22
20
from bzrlib.branch import Branch
 
21
import bzrlib.errors as errors
23
22
from bzrlib.diff import internal_diff
24
23
from bzrlib.inventory import (Inventory, ROOT_ID, InventoryFile,
25
24
    InventoryDirectory, InventoryEntry)
26
 
from bzrlib.osutils import (has_symlinks, rename, pathjoin, is_inside_any, 
27
 
    is_inside_or_parent_of_any)
 
25
import bzrlib.inventory as inventory
 
26
from bzrlib.osutils import has_symlinks, rename, pathjoin
28
27
from bzrlib.tests import TestCase, TestCaseWithTransport
29
28
from bzrlib.transform import TreeTransform
30
29
from bzrlib.uncommit import uncommit
33
32
class TestInventory(TestCase):
34
33
 
35
34
    def test_is_within(self):
 
35
        from bzrlib.osutils import is_inside_any
36
36
 
37
37
        SRC_FOO_C = pathjoin('src', 'foo.c')
38
38
        for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
44
44
        for dirs, fn in [(['src'], 'srccontrol'),
45
45
                         (['src'], 'srccontrol/foo')]:
46
46
            self.assertFalse(is_inside_any(dirs, fn))
47
 
 
48
 
    def test_is_within_or_parent(self):
49
 
        for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
50
 
                         (['src'], 'src/foo.c'),
51
 
                         (['src/bar.c'], 'src'),
52
 
                         (['src/bar.c', 'bla/foo.c'], 'src'),
53
 
                         (['src'], 'src'),
54
 
                         ]:
55
 
            self.assert_(is_inside_or_parent_of_any(dirs, fn))
56
47
            
57
 
        for dirs, fn in [(['src'], 'srccontrol'),
58
 
                         (['srccontrol/foo.c'], 'src'),
59
 
                         (['src'], 'srccontrol/foo')]:
60
 
            self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
61
 
 
62
48
    def test_ids(self):
63
49
        """Test detection of files within selected directories."""
64
50
        inv = Inventory()
86
72
            inv.add_path(*args)
87
73
 
88
74
        self.assertEqual([
89
 
            ('', ROOT_ID),
90
75
            ('Makefile', 'makefile-id'),
91
76
            ('doc', 'doc-id'),
92
77
            ('src', 'src-id'),
94
79
            ('src/hello.c', 'hello-id'),
95
80
            ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
96
81
            
97
 
    def test_iter_entries_by_dir(self):
98
 
        inv = Inventory()
99
 
        
100
 
        for args in [('src', 'directory', 'src-id'), 
101
 
                     ('doc', 'directory', 'doc-id'), 
102
 
                     ('src/hello.c', 'file', 'hello-id'),
103
 
                     ('src/bye.c', 'file', 'bye-id'),
104
 
                     ('zz', 'file', 'zz-id'),
105
 
                     ('src/sub/', 'directory', 'sub-id'),
106
 
                     ('src/zz.c', 'file', 'zzc-id'),
107
 
                     ('src/sub/a', 'file', 'a-id'),
108
 
                     ('Makefile', 'file', 'makefile-id')]:
109
 
            inv.add_path(*args)
110
 
 
111
 
        self.assertEqual([
112
 
            ('', ROOT_ID),
113
 
            ('Makefile', 'makefile-id'),
114
 
            ('doc', 'doc-id'),
115
 
            ('src', 'src-id'),
116
 
            ('zz', 'zz-id'),
117
 
            ('src/bye.c', 'bye-id'),
118
 
            ('src/hello.c', 'hello-id'),
119
 
            ('src/sub', 'sub-id'),
120
 
            ('src/zz.c', 'zzc-id'),
121
 
            ('src/sub/a', 'a-id'),
122
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir()])
123
 
            
124
82
    def test_version(self):
125
83
        """Inventory remembers the text's version."""
126
84
        inv = Inventory()
201
159
        self.assertIsInstance(inventory.make_entry("directory", "name", ROOT_ID),
202
160
            inventory.InventoryDirectory)
203
161
 
204
 
    def test_make_entry_non_normalized(self):
205
 
        orig_normalized_filename = osutils.normalized_filename
206
 
 
207
 
        try:
208
 
            osutils.normalized_filename = osutils._accessible_normalized_filename
209
 
            entry = inventory.make_entry("file", u'a\u030a', ROOT_ID)
210
 
            self.assertEqual(u'\xe5', entry.name)
211
 
            self.assertIsInstance(entry, inventory.InventoryFile)
212
 
 
213
 
            osutils.normalized_filename = osutils._inaccessible_normalized_filename
214
 
            self.assertRaises(errors.InvalidNormalization,
215
 
                    inventory.make_entry, 'file', u'a\u030a', ROOT_ID)
216
 
        finally:
217
 
            osutils.normalized_filename = orig_normalized_filename
218
 
 
219
 
 
220
162
class TestEntryDiffing(TestCaseWithTransport):
221
163
 
222
164
    def setUp(self):
254
196
                          "old_label", self.tree_1,
255
197
                          "/dev/null", None, None,
256
198
                          output)
257
 
        self.assertEqual(output.getvalue(), "--- old_label\n"
258
 
                                            "+++ /dev/null\n"
 
199
        self.assertEqual(output.getvalue(), "--- old_label\t\n"
 
200
                                            "+++ /dev/null\t\n"
259
201
                                            "@@ -1,1 +0,0 @@\n"
260
202
                                            "-foo\n"
261
203
                                            "\n")
266
208
                          "new_label", self.tree_1,
267
209
                          "/dev/null", None, None,
268
210
                          output, reverse=True)
269
 
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
270
 
                                            "+++ new_label\n"
 
211
        self.assertEqual(output.getvalue(), "--- /dev/null\t\n"
 
212
                                            "+++ new_label\t\n"
271
213
                                            "@@ -0,0 +1,1 @@\n"
272
214
                                            "+foo\n"
273
215
                                            "\n")
278
220
                          "/dev/null", self.tree_1, 
279
221
                          "new_label", self.file_2, self.tree_2,
280
222
                          output)
281
 
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
282
 
                                            "+++ new_label\n"
 
223
        self.assertEqual(output.getvalue(), "--- /dev/null\t\n"
 
224
                                            "+++ new_label\t\n"
283
225
                                            "@@ -1,1 +1,1 @@\n"
284
226
                                            "-foo\n"
285
227
                                            "+bar\n"
349
291
        self.inv_1 = self.branch.repository.get_inventory('1')
350
292
        self.file_1 = self.inv_1['fileid']
351
293
        self.file_active = self.wt.inventory['fileid']
352
 
        self.builder = self.branch.get_commit_builder([], timestamp=time.time(), revision_id='2')
353
294
 
354
295
    def test_snapshot_new_revision(self):
355
296
        # This tests that a simple commit with no parents makes a new
356
297
        # revision value in the inventory entry
357
 
        self.file_active.snapshot('2', 'subdir/file', {}, self.wt, self.builder)
 
298
        self.file_active.snapshot('2', 'subdir/file', {}, self.wt, 
 
299
                                  self.branch.repository.weave_store,
 
300
                                  self.branch.get_transaction())
358
301
        # expected outcome - file_1 has a revision id of '2', and we can get
359
302
        # its text of 'file contents' out of the weave.
360
303
        self.assertEqual(self.file_1.revision, '1')
369
312
        #This tests that a simple commit does not make a new entry for
370
313
        # an unchanged inventory entry
371
314
        self.file_active.snapshot('2', 'subdir/file', {'1':self.file_1},
372
 
                                  self.wt, self.builder)
 
315
                                  self.wt, 
 
316
                                  self.branch.repository.weave_store,
 
317
                                  self.branch.get_transaction())
373
318
        self.assertEqual(self.file_1.revision, '1')
374
319
        self.assertEqual(self.file_active.revision, '1')
375
320
        vf = self.branch.repository.weave_store.get_weave(
396
341
        versionfile.clone_text('other', '1', ['1'])
397
342
        self.file_active.snapshot('2', 'subdir/file', 
398
343
                                  {'1':self.file_1, 'other':other_ie},
399
 
                                  self.wt, self.builder)
 
344
                                  self.wt, 
 
345
                                  self.branch.repository.weave_store,
 
346
                                  self.branch.get_transaction())
400
347
        self.assertEqual(self.file_active.revision, '2')
401
348
 
402
349
    def test_snapshot_changed(self):
405
352
        self.file_active.name='newname'
406
353
        rename('subdir/file', 'subdir/newname')
407
354
        self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
408
 
                                  self.wt, self.builder)
 
355
                                  self.wt,
 
356
                                  self.branch.repository.weave_store,
 
357
                                  self.branch.get_transaction())
409
358
        # expected outcome - file_1 has a revision id of '2'
410
359
        self.assertEqual(self.file_active.revision, '2')
411
360
 
533
482
        self.assertEqual(expected_change, change)
534
483
 
535
484
 
 
485
class TestExecutable(TestCaseWithTransport):
 
486
 
 
487
    def test_stays_executable(self):
 
488
        a_id = "a-20051208024829-849e76f7968d7a86"
 
489
        b_id = "b-20051208024829-849e76f7968d7a86"
 
490
        wt = self.make_branch_and_tree('b1')
 
491
        b = wt.branch
 
492
        tt = TreeTransform(wt)
 
493
        tt.new_file('a', tt.root, 'a test\n', a_id, True)
 
494
        tt.new_file('b', tt.root, 'b test\n', b_id, False)
 
495
        tt.apply()
 
496
 
 
497
        self.failUnless(wt.is_executable(a_id), "'a' lost the execute bit")
 
498
 
 
499
        # reopen the tree and ensure it stuck.
 
500
        wt = wt.bzrdir.open_workingtree()
 
501
        self.assertEqual(['a', 'b'], [cn for cn,ie in wt.inventory.iter_entries()])
 
502
 
 
503
        self.failUnless(wt.is_executable(a_id), "'a' lost the execute bit")
 
504
        self.failIf(wt.is_executable(b_id), "'b' gained an execute bit")
 
505
 
 
506
        wt.commit('adding a,b', rev_id='r1')
 
507
 
 
508
        rev_tree = b.repository.revision_tree('r1')
 
509
        self.failUnless(rev_tree.is_executable(a_id), "'a' lost the execute bit")
 
510
        self.failIf(rev_tree.is_executable(b_id), "'b' gained an execute bit")
 
511
 
 
512
        self.failUnless(rev_tree.inventory[a_id].executable)
 
513
        self.failIf(rev_tree.inventory[b_id].executable)
 
514
 
 
515
        # Make sure the entries are gone
 
516
        os.remove('b1/a')
 
517
        os.remove('b1/b')
 
518
        self.failIf(wt.has_id(a_id))
 
519
        self.failIf(wt.has_filename('a'))
 
520
        self.failIf(wt.has_id(b_id))
 
521
        self.failIf(wt.has_filename('b'))
 
522
 
 
523
        # Make sure that revert is able to bring them back,
 
524
        # and sets 'a' back to being executable
 
525
 
 
526
        wt.revert(['a', 'b'], rev_tree, backups=False)
 
527
        self.assertEqual(['a', 'b'], [cn for cn,ie in wt.inventory.iter_entries()])
 
528
 
 
529
        self.failUnless(wt.is_executable(a_id), "'a' lost the execute bit")
 
530
        self.failIf(wt.is_executable(b_id), "'b' gained an execute bit")
 
531
 
 
532
        # Now remove them again, and make sure that after a
 
533
        # commit, they are still marked correctly
 
534
        os.remove('b1/a')
 
535
        os.remove('b1/b')
 
536
        wt.commit('removed', rev_id='r2')
 
537
 
 
538
        self.assertEqual([], [cn for cn,ie in wt.inventory.iter_entries()])
 
539
        self.failIf(wt.has_id(a_id))
 
540
        self.failIf(wt.has_filename('a'))
 
541
        self.failIf(wt.has_id(b_id))
 
542
        self.failIf(wt.has_filename('b'))
 
543
 
 
544
        # Now revert back to the previous commit
 
545
        wt.revert([], rev_tree, backups=False)
 
546
        self.assertEqual(['a', 'b'], [cn for cn,ie in wt.inventory.iter_entries()])
 
547
 
 
548
        self.failUnless(wt.is_executable(a_id), "'a' lost the execute bit")
 
549
        self.failIf(wt.is_executable(b_id), "'b' gained an execute bit")
 
550
 
 
551
        # Now make sure that 'bzr branch' also preserves the
 
552
        # executable bit
 
553
        # TODO: Maybe this should be a blackbox test
 
554
        d2 = b.bzrdir.clone('b2', revision_id='r1')
 
555
        t2 = d2.open_workingtree()
 
556
        b2 = t2.branch
 
557
        self.assertEquals('r1', b2.last_revision())
 
558
 
 
559
        self.assertEqual(['a', 'b'], [cn for cn,ie in t2.inventory.iter_entries()])
 
560
        self.failUnless(t2.is_executable(a_id), "'a' lost the execute bit")
 
561
        self.failIf(t2.is_executable(b_id), "'b' gained an execute bit")
 
562
 
 
563
        # Make sure pull will delete the files
 
564
        t2.pull(b)
 
565
        self.assertEquals('r2', b2.last_revision())
 
566
        self.assertEqual([], [cn for cn,ie in t2.inventory.iter_entries()])
 
567
 
 
568
        # Now commit the changes on the first branch
 
569
        # so that the second branch can pull the changes
 
570
        # and make sure that the executable bit has been copied
 
571
        wt.commit('resurrected', rev_id='r3')
 
572
 
 
573
        t2.pull(b)
 
574
        self.assertEquals('r3', b2.last_revision())
 
575
        self.assertEqual(['a', 'b'], [cn for cn,ie in t2.inventory.iter_entries()])
 
576
 
 
577
        self.failUnless(t2.is_executable(a_id), "'a' lost the execute bit")
 
578
        self.failIf(t2.is_executable(b_id), "'b' gained an execute bit")
 
579
 
 
580
 
536
581
class TestRevert(TestCaseWithTransport):
537
582
 
538
583
    def test_dangling_id(self):