~bzr-pqm/bzr/bzr.dev

1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
1
# Copyright (C) 2006 by Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
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
16
17
"""Test the executable bit under various working tree formats."""
18
19
import os
20
21
from bzrlib.transform import TreeTransform
22
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
23
24
25
class TestExecutable(TestCaseWithWorkingTree):
26
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
27
    def setUp(self):
28
        super(TestExecutable, self).setUp()
29
30
        self.a_id = "a-20051208024829-849e76f7968d7a86"
31
        self.b_id = "b-20051208024829-849e76f7968d7a86"
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
32
        wt = self.make_branch_and_tree('b1')
33
        b = wt.branch
34
        tt = TreeTransform(wt)
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
35
        tt.new_file('a', tt.root, 'a test\n', self.a_id, True)
36
        tt.new_file('b', tt.root, 'b test\n', self.b_id, False)
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
37
        tt.apply()
38
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
39
        self.wt = wt
40
41
    def check_exist(self, tree):
42
        """Just check that both files have the right executable bits set"""
43
        measured = [(cn,ie.executable) 
44
                    for cn,ie in tree.inventory.iter_entries()]
45
        self.assertEqual([('a', True), ('b', False)], measured)
46
        self.failUnless(tree.is_executable(self.a_id),
47
                        "'a' lost the execute bit")
48
        self.failIf(tree.is_executable(self.b_id),
49
                    "'b' gained an execute bit")
50
51
    def check_empty(self, tree, ignore_inv=False):
52
        """Check that the files are truly missing
53
        :param ignore_inv: If you just delete files from a working tree
54
                the inventory still shows them, so don't assert that
55
                the inventory is empty, just that the tree doesn't have them
56
        """
57
        if not ignore_inv:
58
            self.assertEqual([], list(tree.inventory.iter_entries()))
59
        self.failIf(tree.has_id(self.a_id))
60
        self.failIf(tree.has_filename('a'))
61
        self.failIf(tree.has_id(self.b_id))
62
        self.failIf(tree.has_filename('b'))
63
64
    def commit_and_branch(self):
65
        """Commit the current tree, and create a second tree"""
66
        self.wt.commit('adding a,b', rev_id='r1')
67
68
        # Now make sure that 'bzr branch' also preserves the
69
        # executable bit
70
        # TODO: Maybe this should be a blackbox test
71
        dir2 = self.wt.branch.bzrdir.clone('b2', revision_id='r1')
72
        wt2 = dir2.open_workingtree()
73
        self.assertEqual('r1', wt2.last_revision())
74
        self.assertEqual('r1', wt2.branch.last_revision())
75
        return wt2
76
77
    def test_01_is_executable(self):
78
        """Make sure that the tree was created and has the executable bit set"""
79
        self.check_exist(self.wt)
80
81
    def test_02_stays_executable(self):
82
        """reopen the tree and ensure it stuck."""
83
        self.wt = self.wt.bzrdir.open_workingtree()
84
        self.check_exist(self.wt)
85
86
    def test_03_after_commit(self):
87
        """Commit the change, and check the history"""
88
        self.wt.commit('adding a,b', rev_id='r1')
89
90
        rev_tree = self.wt.branch.repository.revision_tree('r1')
91
        self.check_exist(rev_tree)
92
93
    def test_04_after_removed(self):
94
        """Make sure reverting removed files brings them back correctly"""
95
        self.wt.commit('adding a,b', rev_id='r1')
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
96
97
        # Make sure the entries are gone
98
        os.remove('b1/a')
99
        os.remove('b1/b')
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
100
        self.check_empty(self.wt, ignore_inv=True)
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
101
102
        # Make sure that revert is able to bring them back,
103
        # and sets 'a' back to being executable
104
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
105
        rev_tree = self.wt.branch.repository.revision_tree('r1')
106
107
        self.wt.revert(['a', 'b'], rev_tree, backups=False)
108
        self.check_exist(self.wt)
109
110
    def test_05_removed_and_committed(self):
111
        """Check that reverting to an earlier commit restores them"""
112
        self.wt.commit('adding a,b', rev_id='r1')
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
113
114
        # Now remove them again, and make sure that after a
115
        # commit, they are still marked correctly
116
        os.remove('b1/a')
117
        os.remove('b1/b')
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
118
        self.wt.commit('removed', rev_id='r2')
119
120
        self.check_empty(self.wt)
121
122
        rev_tree = self.wt.branch.repository.revision_tree('r1')
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
123
        # Now revert back to the previous commit
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
124
        self.wt.revert([], rev_tree, backups=False)
125
126
        self.check_exist(self.wt)
127
128
    def test_06_branch(self):
129
        """branch b1=>b2 should preserve the executable bits"""
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
130
        # TODO: Maybe this should be a blackbox test
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
131
        wt2 = self.commit_and_branch()
132
133
        self.check_exist(wt2)
134
135
    def test_07_pull(self):
136
        """Test that pull will handle bits correctly"""
137
        wt2 = self.commit_and_branch()
138
139
        os.remove('b1/a')
140
        os.remove('b1/b')
141
        self.wt.commit('removed', rev_id='r2')
142
143
        # now wt2 can pull and the files should be removed
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
144
145
        # Make sure pull will delete the files
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
146
        wt2.pull(self.wt.branch)
147
        self.assertEquals('r2', wt2.last_revision())
148
        self.assertEquals('r2', wt2.branch.last_revision())
149
        self.check_empty(wt2)
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
150
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
151
        # Now restore the files on the first branch and commit
1711.4.30 by John Arbash Meinel
Don't peak under the covers, and test all working tree implementations for executable success (suggested by Robert Collins)
152
        # so that the second branch can pull the changes
153
        # and make sure that the executable bit has been copied
1711.4.33 by John Arbash Meinel
By Martin's suggestion, break the long test into lots of small ones.
154
        rev_tree = self.wt.branch.repository.revision_tree('r1')
155
        self.wt.revert([], rev_tree, backups=False)
156
        self.wt.commit('resurrected', rev_id='r3')
157
158
        self.check_exist(self.wt)
159
160
        wt2.pull(self.wt.branch)
161
        self.assertEquals('r3', wt2.last_revision())
162
        self.assertEquals('r3', wt2.branch.last_revision())
163
        self.check_exist(wt2)
164
165
    def test_08_no_op_revert(self):
166
        """Just do a simple revert without anything changed
167
        
168
        The bits shouldn't swap.
169
        """
170
        self.wt.commit('adding a,b', rev_id='r1')
171
        rev_tree = self.wt.branch.repository.revision_tree('r1')
172
        self.wt.revert([], rev_tree, backups=False)
173
        self.check_exist(self.wt)
174