/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_win32utils.py

  • Committer: Martin
  • Date: 2010-05-20 18:23:17 UTC
  • mto: This revision was merged to the branch mainline in revision 5244.
  • Revision ID: gzlist@googlemail.com-20100520182317-10t33p32m8qcq0m3
Point launchpad links in comments at production server rather than edge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011, 2016 Canonical Ltd
 
1
# Copyright (C) 2007-2010 Canonical Ltd
2
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
17
17
"""Tests for win32utils."""
18
18
 
19
19
import os
 
20
import sys
20
21
 
21
 
from .. import (
 
22
from bzrlib import (
22
23
    osutils,
23
24
    tests,
24
25
    win32utils,
25
26
    )
26
 
from . import (
 
27
from bzrlib.tests import (
 
28
    Feature,
27
29
    TestCase,
28
30
    TestCaseInTempDir,
29
31
    TestSkipped,
30
 
    )
31
 
from .features import backslashdir_feature
32
 
from ..win32utils import glob_expand, get_app_path
33
 
from . import (
34
 
    features,
35
 
    )
36
 
 
37
 
 
38
 
Win32RegistryFeature = features.ModuleAvailableFeature('_winreg')
39
 
 
 
32
    UnicodeFilenameFeature,
 
33
    )
 
34
from bzrlib.tests.features import backslashdir_feature
 
35
from bzrlib.win32utils import glob_expand, get_app_path
 
36
 
 
37
 
 
38
class _RequiredModuleFeature(Feature):
 
39
 
 
40
    def __init__(self, mod_name):
 
41
        self.mod_name = mod_name
 
42
        super(_RequiredModuleFeature, self).__init__()
 
43
 
 
44
    def _probe(self):
 
45
        try:
 
46
            __import__(self.mod_name)
 
47
            return True
 
48
        except ImportError:
 
49
            return False
 
50
 
 
51
    def feature_name(self):
 
52
        return self.mod_name
 
53
 
 
54
Win32RegistryFeature = _RequiredModuleFeature('_winreg')
 
55
CtypesFeature = _RequiredModuleFeature('ctypes')
 
56
Win32comShellFeature = _RequiredModuleFeature('win32com.shell')
 
57
 
 
58
 
 
59
# Tests
 
60
# -----
40
61
 
41
62
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
42
63
 
57
78
                         'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
58
79
 
59
80
    def build_unicode_tree(self):
60
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
81
        self.requireFeature(UnicodeFilenameFeature)
61
82
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/',
62
83
                         u'\u1235/\u1235'])
63
84
 
68
89
        self._run_testset([
69
90
            # no wildcards
70
91
            [[u'a'], [u'a']],
71
 
            [[u'a', u'a'], [u'a', u'a']],
 
92
            [[u'a', u'a' ], [u'a', u'a']],
72
93
 
73
94
            [[u'd'], [u'd']],
74
95
            [[u'd/'], [u'd/']],
98
119
            ])
99
120
 
100
121
    def test_case_insensitive_globbing(self):
101
 
        if os.path.normcase("AbC") == "AbC":
102
 
            self.skipTest("Test requires case insensitive globbing function")
 
122
        self.requireFeature(tests.CaseInsCasePresFilenameFeature)
103
123
        self.build_ascii_tree()
104
124
        self._run_testset([
105
125
            [[u'A'], [u'A']],
162
182
        for a in ('iexplore', 'iexplore.exe'):
163
183
            p = get_app_path(a)
164
184
            d, b = os.path.split(p)
165
 
            self.assertEqual('iexplore.exe', b.lower())
166
 
            self.assertNotEqual('', d)
 
185
            self.assertEquals('iexplore.exe', b.lower())
 
186
            self.assertNotEquals('', d)
167
187
 
168
188
    def test_wordpad(self):
169
189
        # typical windows users should have wordpad in the system
170
190
        # but there is problem: its path has the format REG_EXPAND_SZ
171
191
        # so naive attempt to get the path is not working
172
 
        self.requireFeature(Win32ApiFeature)
173
192
        for a in ('wordpad', 'wordpad.exe'):
174
193
            p = get_app_path(a)
175
194
            d, b = os.path.split(p)
176
 
            self.assertEqual('wordpad.exe', b.lower())
177
 
            self.assertNotEqual('', d)
 
195
            self.assertEquals('wordpad.exe', b.lower())
 
196
            self.assertNotEquals('', d)
178
197
 
179
198
    def test_not_existing(self):
180
199
        p = get_app_path('not-existing')
181
 
        self.assertEqual('not-existing', p)
182
 
 
183
 
 
184
 
class TestLocations(TestCase):
185
 
 
186
 
    _test_needs_features = [features.win32_feature]
 
200
        self.assertEquals('not-existing', p)
 
201
 
 
202
 
 
203
class TestLocationsCtypes(TestCase):
 
204
 
 
205
    _test_needs_features = [CtypesFeature]
187
206
 
188
207
    def assertPathsEqual(self, p1, p2):
189
208
        # TODO: The env var values in particular might return the "short"
190
209
        # version (ie, "C:\DOCUME~1\...").  Its even possible the returned
191
210
        # values will differ only by case - handle these situations as we
192
211
        # come across them.
193
 
        self.assertEqual(p1, p2)
 
212
        self.assertEquals(p1, p2)
194
213
 
195
214
    def test_appdata_not_using_environment(self):
196
215
        # Test that we aren't falling back to the environment
197
216
        first = win32utils.get_appdata_location()
198
 
        self.overrideEnv("APPDATA", None)
 
217
        self._captureVar("APPDATA", None)
199
218
        self.assertPathsEqual(first, win32utils.get_appdata_location())
200
219
 
201
220
    def test_appdata_matches_environment(self):
212
231
    def test_local_appdata_not_using_environment(self):
213
232
        # Test that we aren't falling back to the environment
214
233
        first = win32utils.get_local_appdata_location()
215
 
        self.overrideEnv("LOCALAPPDATA", None)
 
234
        self._captureVar("LOCALAPPDATA", None)
216
235
        self.assertPathsEqual(first, win32utils.get_local_appdata_location())
217
236
 
218
237
    def test_local_appdata_matches_environment(self):
221
240
        lad = win32utils.get_local_appdata_location()
222
241
        env = os.environ.get("LOCALAPPDATA")
223
242
        if env:
224
 
            # XXX - See bug 262874, which asserts the correct encoding is
225
 
            # 'mbcs'
 
243
            # XXX - See bug 262874, which asserts the correct encoding is 'mbcs'
226
244
            encoding = osutils.get_user_encoding()
227
245
            self.assertPathsEqual(lad, env.decode(encoding))
228
246
 
229
247
 
 
248
class TestLocationsPywin32(TestLocationsCtypes):
 
249
 
 
250
    _test_needs_features = [Win32comShellFeature]
 
251
 
 
252
    def setUp(self):
 
253
        super(TestLocationsPywin32, self).setUp()
 
254
        # We perform the exact same tests after disabling the use of ctypes.
 
255
        # This causes the implementation to fall back to pywin32.
 
256
        self.overrideAttr(win32utils, 'has_ctypes', False)
 
257
        # FIXME: this should be done by parametrization -- vila 100123
 
258
 
 
259
 
230
260
class TestSetHidden(TestCaseInTempDir):
231
261
 
232
 
    _test_needs_features = [features.win32_feature]
233
 
 
234
262
    def test_unicode_dir(self):
235
263
        # we should handle unicode paths without errors
236
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
264
        self.requireFeature(UnicodeFilenameFeature)
237
265
        os.mkdir(u'\u1234')
238
266
        win32utils.set_file_attr_hidden(u'\u1234')
239
267
 
240
268
    def test_dot_bzr_in_unicode_dir(self):
241
269
        # we should not raise traceback if we try to set hidden attribute
242
270
        # on .bzr directory below unicode path
243
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
271
        self.requireFeature(UnicodeFilenameFeature)
244
272
        os.makedirs(u'\u1234\\.bzr')
245
273
        path = osutils.abspath(u'\u1234\\.bzr')
246
274
        win32utils.set_file_attr_hidden(path)
248
276
 
249
277
class Test_CommandLineToArgv(tests.TestCaseInTempDir):
250
278
 
251
 
    def assertCommandLine(self, expected, line, argv=None,
252
 
                          single_quotes_allowed=False):
 
279
    def assertCommandLine(self, expected, line, single_quotes_allowed=False):
253
280
        # Strictly speaking we should respect parameter order versus glob
254
281
        # expansions, but it's not really worth the effort here
255
 
        if argv is None:
256
 
            argv = [line]
257
 
        argv = win32utils._command_line_to_argv(
258
 
            line, argv, single_quotes_allowed=single_quotes_allowed)
 
282
        argv = win32utils._command_line_to_argv(line,
 
283
                single_quotes_allowed=single_quotes_allowed)
259
284
        self.assertEqual(expected, sorted(argv))
260
285
 
261
286
    def test_glob_paths(self):
273
298
        self.assertCommandLine([u'a/*.c'], '"a/*.c"')
274
299
        self.assertCommandLine([u"'a/*.c'"], "'a/*.c'")
275
300
        self.assertCommandLine([u'a/*.c'], "'a/*.c'",
276
 
                               single_quotes_allowed=True)
 
301
            single_quotes_allowed=True)
277
302
 
278
303
    def test_slashes_changed(self):
279
304
        # Quoting doesn't change the supplied args
280
305
        self.assertCommandLine([u'a\\*.c'], '"a\\*.c"')
281
306
        self.assertCommandLine([u'a\\*.c'], "'a\\*.c'",
282
 
                               single_quotes_allowed=True)
 
307
            single_quotes_allowed=True)
283
308
        # Expands the glob, but nothing matches, swaps slashes
284
309
        self.assertCommandLine([u'a/*.c'], 'a\\*.c')
285
310
        self.assertCommandLine([u'a/?.c'], 'a\\?.c')
288
313
 
289
314
    def test_single_quote_support(self):
290
315
        self.assertCommandLine(["add", "let's-do-it.txt"],
291
 
                               "add let's-do-it.txt",
292
 
                               ["add", "let's-do-it.txt"])
293
 
        self.expectFailure("Using single quotes breaks trimming from argv",
294
 
                           self.assertCommandLine, ["add", "lets do it.txt"],
295
 
                           "add 'lets do it.txt'", [
296
 
                               "add", "'lets", "do", "it.txt'"],
297
 
                           single_quotes_allowed=True)
 
316
            "add let's-do-it.txt")
 
317
        self.assertCommandLine(["add", "lets do it.txt"],
 
318
            "add 'lets do it.txt'", single_quotes_allowed=True)
298
319
 
299
320
    def test_case_insensitive_globs(self):
300
 
        if os.path.normcase("AbC") == "AbC":
301
 
            self.skipTest("Test requires case insensitive globbing function")
 
321
        self.requireFeature(tests.CaseInsCasePresFilenameFeature)
302
322
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
303
323
        self.assertCommandLine([u'A/b.c'], 'A/B*')
304
324
 
306
326
        self.requireFeature(backslashdir_feature)
307
327
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
308
328
        self.assertCommandLine([u'a/b.c'], 'a\\b*')
309
 
 
310
 
    def test_with_pdb(self):
311
 
        """Check stripping Python arguments before bzr script per lp:587868"""
312
 
        self.assertCommandLine([u"rocks"], "-m pdb rocks", ["rocks"])
313
 
        self.build_tree(['d/', 'd/f1', 'd/f2'])
314
 
        self.assertCommandLine([u"rm", u"x*"], "-m pdb rm x*", ["rm", u"x*"])
315
 
        self.assertCommandLine([u"add", u"d/f1", u"d/f2"], "-m pdb add d/*",
316
 
                               ["add", u"d/*"])
317
 
 
318
 
 
319
 
class TestGetEnvironUnicode(tests.TestCase):
320
 
    """Tests for accessing the environment via the windows wide api"""
321
 
 
322
 
    _test_needs_features = [features.win32_feature]
323
 
 
324
 
    def setUp(self):
325
 
        super(TestGetEnvironUnicode, self).setUp()
326
 
        self.overrideEnv("TEST", "1")
327
 
 
328
 
    def test_get(self):
329
 
        """In the normal case behaves the same as os.environ access"""
330
 
        self.assertEqual("1", win32utils.get_environ_unicode("TEST"))
331
 
 
332
 
    def test_unset(self):
333
 
        """A variable not present in the environment gives None by default"""
334
 
        del os.environ["TEST"]
335
 
        self.assertIs(None, win32utils.get_environ_unicode("TEST"))
336
 
 
337
 
    def test_unset_default(self):
338
 
        """A variable not present in the environment gives passed default"""
339
 
        del os.environ["TEST"]
340
 
        self.assertIs("a", win32utils.get_environ_unicode("TEST", "a"))
341
 
 
342
 
    def test_unicode(self):
343
 
        """A non-ascii variable is returned as unicode"""
344
 
        unicode_val = u"\xa7"  # non-ascii character present in many encodings
345
 
        try:
346
 
            bytes_val = unicode_val.encode(osutils.get_user_encoding())
347
 
        except UnicodeEncodeError:
348
 
            self.skipTest("Couldn't encode non-ascii string for environ")
349
 
        os.environ["TEST"] = bytes_val
350
 
        self.assertEqual(unicode_val, win32utils.get_environ_unicode("TEST"))
351
 
 
352
 
    def test_long(self):
353
 
        """A variable bigger than heuristic buffer size is still accessible"""
354
 
        big_val = "x" * (2 << 10)
355
 
        os.environ["TEST"] = big_val
356
 
        self.assertEqual(big_val, win32utils.get_environ_unicode("TEST"))
357
 
 
358
 
    def test_unexpected_error(self):
359
 
        """An error from the underlying platform function is propogated"""
360
 
        ERROR_INVALID_PARAMETER = 87
361
 
        SetLastError = win32utils.ctypes.windll.kernel32.SetLastError
362
 
 
363
 
        def failer(*args, **kwargs):
364
 
            SetLastError(ERROR_INVALID_PARAMETER)
365
 
            return 0
366
 
        self.overrideAttr(win32utils.get_environ_unicode, "_c_function",
367
 
                          failer)
368
 
        e = self.assertRaises(WindowsError,
369
 
                              win32utils.get_environ_unicode, "TEST")
370
 
        self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)