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