~bzr-pqm/bzr/bzr.dev

5273.1.8 by Vincent Ladeuil
Merge bzr.dev into cleanup
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
3794.5.9 by Mark Hammond
Correct line-endings.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3794.5.9 by Mark Hammond
Correct line-endings.
16
#
17
18
"""Tests variations of case-insensitive and case-preserving file-systems."""
19
20
import os
21
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
22
from bzrlib import (
23
    osutils,
24
    tests,
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
25
    )
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
26
from bzrlib.tests import KnownFailure
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
27
from bzrlib.osutils import canonical_relpath, pathjoin
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
28
from bzrlib.tests.script import run_script
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
29
from bzrlib.tests.features import (
30
    CaseInsCasePresFilenameFeature,
31
    )
32
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
33
34
35
class TestCICPBase(tests.TestCaseWithTransport):
3794.5.23 by Mark Hammond
reoganize tests into categories.
36
    """Base class for tests on a case-insensitive, case-preserving filesystem.
3794.5.9 by Mark Hammond
Correct line-endings.
37
    """
38
39
    _test_needs_features = [CaseInsCasePresFilenameFeature]
40
41
    def _make_mixed_case_tree(self):
42
        """Make a working tree with mixed-case filenames."""
43
        wt = self.make_branch_and_tree('.')
44
        # create a file on disk with the mixed-case parent and base name
45
        self.build_tree(['CamelCaseParent/', 'lowercaseparent/'])
46
        self.build_tree_contents([('CamelCaseParent/CamelCase', 'camel case'),
47
                                  ('lowercaseparent/lowercase', 'lower case'),
48
                                  ('lowercaseparent/mixedCase', 'mixedCasecase'),
49
                                 ])
50
        return wt
51
3794.5.31 by Mark Hammond
bulk of the simple review comments from igc.
52
3794.5.23 by Mark Hammond
reoganize tests into categories.
53
class TestAdd(TestCICPBase):
4241.9.2 by Vincent Ladeuil
Fix most of cicp related failures on OSX.
54
3794.5.9 by Mark Hammond
Correct line-endings.
55
    def test_add_simple(self):
56
        """Test add always uses the case of the filename reported by the os."""
57
        wt = self.make_branch_and_tree('.')
58
        # create a file on disk with the mixed-case name
59
        self.build_tree(['CamelCase'])
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
60
        run_script(self, """
61
            $ bzr add camelcase
62
            adding CamelCase
63
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
64
65
    def test_add_subdir(self):
66
        """test_add_simple but with subdirectories tested too."""
67
        wt = self.make_branch_and_tree('.')
68
        # create a file on disk with the mixed-case parent and base name
69
        self.build_tree(['CamelCaseParent/', 'CamelCaseParent/CamelCase'])
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
70
        run_script(self, """
71
            $ bzr add camelcaseparent/camelcase
72
            adding CamelCaseParent
73
            adding CamelCaseParent/CamelCase
74
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
75
76
    def test_add_implied(self):
77
        """test add with no args sees the correct names."""
78
        wt = self.make_branch_and_tree('.')
79
        # create a file on disk with the mixed-case parent and base name
80
        self.build_tree(['CamelCaseParent/', 'CamelCaseParent/CamelCase'])
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
81
        run_script(self, """
82
            $ bzr add
83
            adding CamelCaseParent
84
            adding CamelCaseParent/CamelCase
85
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
86
3794.5.23 by Mark Hammond
reoganize tests into categories.
87
    def test_re_add(self):
88
        """Test than when a file has 'unintentionally' changed case, we can't
89
        add a new entry using the new case."""
90
        wt = self.make_branch_and_tree('.')
91
        # create a file on disk with the mixed-case name
92
        self.build_tree(['MixedCase'])
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
93
        run_script(self, """
94
            $ bzr add MixedCase
95
            adding MixedCase
96
            """)
3794.5.23 by Mark Hammond
reoganize tests into categories.
97
        # 'accidently' rename the file on disk
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
98
        osutils.rename('MixedCase', 'mixedcase')
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
99
        run_script(self, """
100
            $ bzr add mixedcase
101
            """)
3794.5.23 by Mark Hammond
reoganize tests into categories.
102
103
    def test_re_add_dir(self):
104
        # like re-add, but tests when the operation is on a directory.
105
        """Test than when a file has 'unintentionally' changed case, we can't
106
        add a new entry using the new case."""
107
        wt = self.make_branch_and_tree('.')
108
        # create a file on disk with the mixed-case name
109
        self.build_tree(['MixedCaseParent/', 'MixedCaseParent/MixedCase'])
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
110
        run_script(self, """
111
            $ bzr add MixedCaseParent
112
            adding MixedCaseParent
113
            adding MixedCaseParent/MixedCase
114
            """)
3794.5.23 by Mark Hammond
reoganize tests into categories.
115
        # 'accidently' rename the directory on disk
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
116
        osutils.rename('MixedCaseParent', 'mixedcaseparent')
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
117
        run_script(self, """
118
            $ bzr add mixedcaseparent
119
            """)
3794.5.23 by Mark Hammond
reoganize tests into categories.
120
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
121
    def test_add_not_found(self):
122
        """Test add when the input file doesn't exist."""
123
        wt = self.make_branch_and_tree('.')
124
        # create a file on disk with the mixed-case name
125
        self.build_tree(['MixedCaseParent/', 'MixedCaseParent/MixedCase'])
126
        expected_fname = pathjoin(wt.basedir, "MixedCaseParent", "notfound")
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
127
        run_script(self, """
128
            $ bzr add mixedcaseparent/notfound
129
            2>bzr: ERROR: No such file: %s
130
            """ % (repr(expected_fname),))
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
131
3794.5.23 by Mark Hammond
reoganize tests into categories.
132
133
class TestMove(TestCICPBase):
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
134
3794.5.9 by Mark Hammond
Correct line-endings.
135
    def test_mv_newname(self):
136
        wt = self._make_mixed_case_tree()
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
137
        run_script(self, """
5485.1.1 by Martin
Adapt missed script tests for CICP filesystems to bug 637830 changes
138
            $ bzr add -q
139
            $ bzr ci -qm message
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
140
            $ bzr mv camelcaseparent/camelcase camelcaseparent/NewCamelCase
141
            CamelCaseParent/CamelCase => CamelCaseParent/NewCamelCase
142
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
143
144
    def test_mv_newname_after(self):
145
        wt = self._make_mixed_case_tree()
146
        # In this case we can specify the incorrect case for the destination,
147
        # as we use --after, so the file-system is sniffed.
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
148
        run_script(self, """
5485.1.1 by Martin
Adapt missed script tests for CICP filesystems to bug 637830 changes
149
            $ bzr add -q
150
            $ bzr ci -qm message
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
151
            $ mv CamelCaseParent/CamelCase CamelCaseParent/NewCamelCase
152
            $ bzr mv --after camelcaseparent/camelcase camelcaseparent/newcamelcase
153
            CamelCaseParent/CamelCase => CamelCaseParent/NewCamelCase
154
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
155
3794.5.21 by Mark Hammond
More cicp-filesystem tests
156
    def test_mv_newname_exists(self):
157
        # test a mv, but when the target already exists with a name that
158
        # differs only by case.
159
        wt = self._make_mixed_case_tree()
160
        self.run_bzr('add')
161
        self.run_bzr('ci -m message')
5283.4.3 by Martin Pool
Remove old check_error_output helper
162
        run_script(self, """
163
            $ bzr mv camelcaseparent/camelcase LOWERCASEPARENT/LOWERCASE
164
            2>bzr: ERROR: Could not move CamelCase => lowercase: \
165
lowercaseparent/lowercase is already versioned.
166
            """)
3794.5.21 by Mark Hammond
More cicp-filesystem tests
167
168
    def test_mv_newname_exists_after(self):
169
        # test a 'mv --after', but when the target already exists with a name
170
        # that differs only by case.  Note that this is somewhat unlikely
171
        # but still reasonable.
172
        wt = self._make_mixed_case_tree()
173
        self.run_bzr('add')
174
        self.run_bzr('ci -m message')
175
        # Remove the source and create a destination file on disk with a different case.
176
        # bzr should report that the filename is already versioned.
177
        os.unlink('CamelCaseParent/CamelCase')
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
178
        osutils.rename('lowercaseparent/lowercase', 'lowercaseparent/LOWERCASE')
5283.4.3 by Martin Pool
Remove old check_error_output helper
179
        run_script(self, """
180
            $ bzr mv --after camelcaseparent/camelcase LOWERCASEPARENT/LOWERCASE
181
            2>bzr: ERROR: Could not move CamelCase => lowercase: \
182
lowercaseparent/lowercase is already versioned.
183
            """)
3794.5.21 by Mark Hammond
More cicp-filesystem tests
184
3794.5.9 by Mark Hammond
Correct line-endings.
185
    def test_mv_newname_root(self):
186
        wt = self._make_mixed_case_tree()
187
        self.run_bzr('add')
188
        self.run_bzr('ci -m message')
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
189
        run_script(self, """
190
            $ bzr mv camelcaseparent NewCamelCaseParent
191
            CamelCaseParent => NewCamelCaseParent
192
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
193
194
    def test_mv_newname_root_after(self):
195
        wt = self._make_mixed_case_tree()
196
        self.run_bzr('add')
197
        self.run_bzr('ci -m message')
198
        # In this case we can specify the incorrect case for the destination,
199
        # as we use --after, so the file-system is sniffed.
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
200
        run_script(self, """
201
            $ mv CamelCaseParent NewCamelCaseParent
202
            $ bzr mv --after camelcaseparent NewCamelCaseParent
203
            CamelCaseParent => NewCamelCaseParent
204
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
205
206
    def test_mv_newcase(self):
207
        wt = self._make_mixed_case_tree()
208
        self.run_bzr('add')
209
        self.run_bzr('ci -m message')
210
3794.5.21 by Mark Hammond
More cicp-filesystem tests
211
        # perform a mv to the new case - we expect bzr to accept the new
212
        # name, as specified, and rename the file on the file-system too.
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
213
        run_script(self, """
214
            $ bzr mv camelcaseparent/camelcase camelcaseparent/camelCase
215
            CamelCaseParent/CamelCase => CamelCaseParent/camelCase
216
            """)
3794.5.21 by Mark Hammond
More cicp-filesystem tests
217
        self.failUnlessEqual(canonical_relpath(wt.basedir, 'camelcaseparent/camelcase'),
218
                             'CamelCaseParent/camelCase')
219
220
    def test_mv_newcase_after(self):
221
        wt = self._make_mixed_case_tree()
222
        self.run_bzr('add')
223
        self.run_bzr('ci -m message')
224
3794.5.9 by Mark Hammond
Correct line-endings.
225
        # perform a mv to the new case - we must ensure the file-system has the
226
        # new case first.
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
227
        osutils.rename('CamelCaseParent/CamelCase', 'CamelCaseParent/camelCase')
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
228
        run_script(self, """
229
            $ bzr mv --after camelcaseparent/camelcase camelcaseparent/camelCase
230
            CamelCaseParent/CamelCase => CamelCaseParent/camelCase
231
            """)
3794.5.21 by Mark Hammond
More cicp-filesystem tests
232
        # bzr should not have renamed the file to a different case
233
        self.failUnlessEqual(canonical_relpath(wt.basedir, 'camelcaseparent/camelcase'),
234
                             'CamelCaseParent/camelCase')
3794.5.9 by Mark Hammond
Correct line-endings.
235
236
    def test_mv_multiple(self):
237
        wt = self._make_mixed_case_tree()
238
        self.run_bzr('add')
239
        self.run_bzr('ci -m message')
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
240
        run_script(self, """
241
            $ bzr mv LOWercaseparent/LOWercase LOWercaseparent/MIXEDCase camelcaseparent
242
            lowercaseparent/lowercase => CamelCaseParent/lowercase
243
            lowercaseparent/mixedCase => CamelCaseParent/mixedCase
244
            """)
3794.5.9 by Mark Hammond
Correct line-endings.
245
3794.5.23 by Mark Hammond
reoganize tests into categories.
246
247
class TestMisc(TestCICPBase):
4651.2.1 by Vincent Ladeuil
Catch up fix for #347649.
248
3794.5.23 by Mark Hammond
reoganize tests into categories.
249
    def test_status(self):
250
        wt = self._make_mixed_case_tree()
251
        self.run_bzr('add')
5283.4.2 by Martin Pool
Change test_filesystem_cicp to use scripts rather than ExternalBase
252
        run_script(self, """
253
            $ bzr status camelcaseparent/camelcase LOWERCASEPARENT/LOWERCASE
254
            added:
255
              CamelCaseParent/
256
              CamelCaseParent/CamelCase
257
              lowercaseparent/
258
              lowercaseparent/lowercase
259
            """)
3794.5.23 by Mark Hammond
reoganize tests into categories.
260
261
    def test_ci(self):
262
        wt = self._make_mixed_case_tree()
263
        self.run_bzr('add')
264
265
        got = self.run_bzr('ci -m message camelcaseparent LOWERCASEPARENT')[1]
266
        for expected in ['CamelCaseParent', 'lowercaseparent',
267
                         'CamelCaseParent/CamelCase', 'lowercaseparent/lowercase']:
268
            self.assertContainsRe(got, 'added ' + expected + '\n')
269
270
    def test_rm(self):
271
        wt = self._make_mixed_case_tree()
272
        self.run_bzr('add')
273
        self.run_bzr('ci -m message')
274
275
        got = self.run_bzr('rm camelcaseparent LOWERCASEPARENT')[1]
276
        for expected in ['lowercaseparent/lowercase', 'CamelCaseParent/CamelCase']:
277
            self.assertContainsRe(got, 'deleted ' + expected + '\n')
278
3794.5.10 by Mark Hammond
Add comments about commands that should still get love.
279
280
    # The following commands need tests and/or cicp lovin':
281
    # update, remove, file_id, file_path, diff, log, touching_revisions, ls,
3794.5.31 by Mark Hammond
bulk of the simple review comments from igc.
282
    # ignore, cat, revert, resolve.