/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 brzlib/tests/features.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""A collection of commonly used 'Features' to optionally run tests.
18
18
"""
19
19
 
20
 
import importlib
21
20
import os
22
21
import subprocess
23
22
import stat
24
23
import sys
25
24
import tempfile
26
 
import warnings
27
25
 
28
 
from .. import (
 
26
from brzlib import (
29
27
    osutils,
30
28
    symbol_versioning,
31
29
    )
67
65
    def feature_name(self):
68
66
        return 'symlinks'
69
67
 
70
 
 
71
68
SymlinkFeature = _SymlinkFeature()
72
69
 
73
70
 
79
76
    def feature_name(self):
80
77
        return 'hardlinks'
81
78
 
82
 
 
83
79
HardlinkFeature = _HardlinkFeature()
84
80
 
85
81
 
91
87
    def feature_name(self):
92
88
        return 'filesystem fifos'
93
89
 
94
 
 
95
90
OsFifoFeature = _OsFifoFeature()
96
91
 
97
92
 
116
111
            # for some reason.
117
112
            return True
118
113
 
119
 
 
120
114
UnicodeFilenameFeature = _UnicodeFilenameFeature()
121
115
 
122
116
 
141
135
 
142
136
    def _ensure(self):
143
137
        if self._feature is None:
144
 
            from breezy import pyutils
 
138
            from brzlib import pyutils
145
139
            depr_msg = self._dep_version % ('%s.%s'
146
140
                                            % (self._module, self._name))
147
141
            use_msg = ' Use %s.%s instead.' % (self._replacement_module,
167
161
    :ivar module: The module if it is available, else None.
168
162
    """
169
163
 
170
 
    def __init__(self, module_name, ignore_warnings=None):
 
164
    def __init__(self, module_name):
171
165
        super(ModuleAvailableFeature, self).__init__()
172
166
        self.module_name = module_name
173
 
        if ignore_warnings is None:
174
 
            ignore_warnings = ()
175
 
        self.ignore_warnings = ignore_warnings
176
167
 
177
168
    def _probe(self):
178
169
        sentinel = object()
179
170
        module = sys.modules.get(self.module_name, sentinel)
180
171
        if module is sentinel:
181
 
            with warnings.catch_warnings():
182
 
                for warning_category in self.ignore_warnings:
183
 
                    warnings.simplefilter('ignore', warning_category)
184
 
                try:
185
 
                    self._module = importlib.import_module(self.module_name)
186
 
                except ImportError:
187
 
                    return False
 
172
            try:
 
173
                self._module = __import__(self.module_name, {}, {}, [''])
188
174
                return True
 
175
            except ImportError:
 
176
                return False
189
177
        else:
190
178
            self._module = module
191
179
            return True
200
188
        return self.module_name
201
189
 
202
190
 
203
 
class PluginLoadedFeature(Feature):
204
 
    """Check whether a plugin with specific name is loaded.
205
 
 
206
 
    This is different from ModuleAvailableFeature, because
207
 
    plugins can be available but explicitly disabled
208
 
    (e.g. through BRZ_DISABLE_PLUGINS=blah).
209
 
 
210
 
    :ivar plugin_name: The name of the plugin
211
 
    """
212
 
 
213
 
    def __init__(self, plugin_name):
214
 
        super(PluginLoadedFeature, self).__init__()
215
 
        self.plugin_name = plugin_name
216
 
 
217
 
    def _probe(self):
218
 
        from breezy.plugin import get_loaded_plugin
219
 
        return (get_loaded_plugin(self.plugin_name) is not None)
220
 
 
221
 
    @property
222
 
    def plugin(self):
223
 
        from breezy.plugin import get_loaded_plugin
224
 
        return get_loaded_plugin(self.plugin_name)
225
 
 
226
 
    def feature_name(self):
227
 
        return '%s plugin' % self.plugin_name
228
 
 
229
 
 
230
191
class _HTTPSServerFeature(Feature):
231
192
    """Some tests want an https Server, check if one is available.
232
193
 
236
197
 
237
198
    def _probe(self):
238
199
        try:
239
 
            import ssl  # noqa: F401
 
200
            import ssl
240
201
            return True
241
202
        except ImportError:
242
203
            return False
256
217
            return True
257
218
        return False
258
219
 
259
 
 
260
220
ByteStringNamedFilesystem = _ByteStringNamedFilesystem()
261
221
 
262
222
 
268
228
            return True
269
229
        return False
270
230
 
271
 
 
272
231
UTF8Filesystem = _UTF8Filesystem()
273
232
 
274
233
 
276
235
    """Does this platform support the breakin feature?"""
277
236
 
278
237
    def _probe(self):
279
 
        from breezy import breakin
 
238
        from brzlib import breakin
280
239
        if breakin.determine_signal() is None:
281
240
            return False
282
241
        if sys.platform == 'win32':
284
243
            # We trigger SIGBREAK via a Console api so we need ctypes to
285
244
            # access the function
286
245
            try:
287
 
                import ctypes  # noqa: F401
 
246
                import ctypes
288
247
            except OSError:
289
248
                return False
290
249
        return True
307
266
            name = osutils.normpath(name)
308
267
            base, rel = osutils.split(name)
309
268
            found_rel = osutils.canonical_relpath(base, name)
310
 
            return (found_rel == rel and
311
 
                    os.path.isfile(name.upper()) and
312
 
                    os.path.isfile(name.lower()))
 
269
            return (found_rel == rel
 
270
                    and os.path.isfile(name.upper())
 
271
                    and os.path.isfile(name.lower()))
313
272
        finally:
314
273
            os.close(fileno)
315
274
            os.remove(name)
317
276
    def feature_name(self):
318
277
        return "case-insensitive case-preserving filesystem"
319
278
 
320
 
 
321
279
CaseInsCasePresFilenameFeature = _CaseInsCasePresFilenameFeature()
322
280
 
323
281
 
332
290
        if CaseInsCasePresFilenameFeature.available():
333
291
            return False
334
292
 
335
 
        from breezy import tests
 
293
        from brzlib import tests
336
294
 
337
295
        if tests.TestCaseWithMemoryTransport.TEST_ROOT is None:
338
296
            root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
340
298
        else:
341
299
            root = tests.TestCaseWithMemoryTransport.TEST_ROOT
342
300
        tdir = osutils.mkdtemp(prefix='case-sensitive-probe-', suffix='',
343
 
                               dir=root)
 
301
            dir=root)
344
302
        name_a = osutils.pathjoin(tdir, 'a')
345
303
        name_A = osutils.pathjoin(tdir, 'A')
346
304
        os.mkdir(name_a)
351
309
    def feature_name(self):
352
310
        return 'case-insensitive filesystem'
353
311
 
354
 
 
355
312
CaseInsensitiveFilesystemFeature = _CaseInsensitiveFilesystemFeature()
356
313
 
357
314
 
368
325
    def feature_name(self):
369
326
        return 'case-sensitive filesystem'
370
327
 
371
 
 
372
328
# new coding style is for feature instances to be lowercase
373
329
case_sensitive_filesystem_feature = _CaseSensitiveFilesystemFeature()
374
330
 
389
345
 
390
346
not_running_as_root = _NotRunningAsRoot()
391
347
 
392
 
# Apport uses deprecated imp module on python3.
393
 
apport = ModuleAvailableFeature(
394
 
    'apport.report',
395
 
    ignore_warnings=[DeprecationWarning, PendingDeprecationWarning])
396
 
gpg = ModuleAvailableFeature('gpg')
 
348
apport = ModuleAvailableFeature('apport')
 
349
gpgme = ModuleAvailableFeature('gpgme')
397
350
lzma = ModuleAvailableFeature('lzma')
398
351
meliae = ModuleAvailableFeature('meliae.scanner')
399
352
paramiko = ModuleAvailableFeature('paramiko')
 
353
pycurl = ModuleAvailableFeature('pycurl')
400
354
pywintypes = ModuleAvailableFeature('pywintypes')
401
355
subunit = ModuleAvailableFeature('subunit')
402
356
testtools = ModuleAvailableFeature('testtools')
403
 
flake8 = ModuleAvailableFeature('flake8.api.legacy')
404
357
 
405
 
lsprof_feature = ModuleAvailableFeature('breezy.lsprof')
406
 
pkg_resources_feature = ModuleAvailableFeature('pkg_resources')
 
358
compiled_patiencediff_feature = ModuleAvailableFeature(
 
359
    'brzlib._patiencediff_c')
 
360
lsprof_feature = ModuleAvailableFeature('brzlib.lsprof')
407
361
 
408
362
 
409
363
class _BackslashDirSeparatorFeature(Feature):
419
373
    def feature_name(self):
420
374
        return "Filesystem treats '\\' as a directory separator."
421
375
 
422
 
 
423
376
backslashdir_feature = _BackslashDirSeparatorFeature()
424
377
 
425
378
 
429
382
    def _probe(self):
430
383
        return os.name == 'posix' and hasattr(os, 'chown')
431
384
 
432
 
 
433
385
chown_feature = _ChownFeature()
434
386
 
435
387
 
473
425
            os.close(fd)
474
426
            osutils.chmod_if_possible(name, write_perms)
475
427
 
476
 
            read_perms = os.stat(name).st_mode & 0o777
 
428
            read_perms = os.stat(name).st_mode & 0777
477
429
            os.unlink(name)
478
430
            return (write_perms == read_perms)
479
431
 
491
443
    def _probe(self):
492
444
        try:
493
445
            proc = subprocess.Popen(['strace'],
494
 
                                    stderr=subprocess.PIPE,
495
 
                                    stdout=subprocess.PIPE)
 
446
                stderr=subprocess.PIPE,
 
447
                stdout=subprocess.PIPE)
496
448
            proc.communicate()
497
449
            return True
498
 
        except OSError as e:
499
 
            import errno
 
450
        except OSError, e:
500
451
            if e.errno == errno.ENOENT:
501
452
                # strace is not installed
502
453
                return False
517
468
            return False
518
469
        try:
519
470
            proc = subprocess.Popen(['attrib', '.'], stdout=subprocess.PIPE)
520
 
        except OSError:
 
471
        except OSError, e:
521
472
            return False
522
473
        return (0 == proc.wait())
523
474
 
543
494
win32_feature = Win32Feature()
544
495
 
545
496
 
546
 
class _BackslashFilenameFeature(Feature):
547
 
    """Does the filesystem support backslashes in filenames?"""
548
 
 
549
 
    def _probe(self):
550
 
 
551
 
        try:
552
 
            fileno, name = tempfile.mkstemp(prefix='bzr\\prefix')
553
 
        except (IOError, OSError):
554
 
            return False
555
 
        else:
556
 
            try:
557
 
                os.stat(name)
558
 
            except (IOError, OSError):
559
 
                # mkstemp succeeded but the file wasn't actually created
560
 
                return False
561
 
            os.close(fileno)
562
 
            os.remove(name)
563
 
            return True
564
 
 
565
 
 
566
 
BackslashFilenameFeature = _BackslashFilenameFeature()
567
 
 
568
 
 
569
 
class PathFeature(Feature):
570
 
    """Feature testing whether a particular path exists."""
571
 
 
572
 
    def __init__(self, path):
573
 
        super(PathFeature, self).__init__()
574
 
        self.path = path
575
 
 
576
 
    def _probe(self):
577
 
        return os.path.exists(self.path)
 
497
class _ColorFeature(Feature):
 
498
 
 
499
    def _probe(self):
 
500
        from brzlib._termcolor import allow_color
 
501
        return allow_color()
578
502
 
579
503
    def feature_name(self):
580
 
        return "%s exists" % self.path
 
504
        return "Terminal supports color."
 
505
 
 
506
ColorFeature = _ColorFeature()