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

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

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
 
20
from __future__ import absolute_import
 
21
 
21
22
import os
22
23
import subprocess
23
24
import stat
24
25
import sys
25
26
import tempfile
26
 
import warnings
27
27
 
28
28
from .. import (
29
29
    osutils,
67
67
    def feature_name(self):
68
68
        return 'symlinks'
69
69
 
70
 
 
71
70
SymlinkFeature = _SymlinkFeature()
72
71
 
73
72
 
79
78
    def feature_name(self):
80
79
        return 'hardlinks'
81
80
 
82
 
 
83
81
HardlinkFeature = _HardlinkFeature()
84
82
 
85
83
 
91
89
    def feature_name(self):
92
90
        return 'filesystem fifos'
93
91
 
94
 
 
95
92
OsFifoFeature = _OsFifoFeature()
96
93
 
97
94
 
116
113
            # for some reason.
117
114
            return True
118
115
 
119
 
 
120
116
UnicodeFilenameFeature = _UnicodeFilenameFeature()
121
117
 
122
118
 
167
163
    :ivar module: The module if it is available, else None.
168
164
    """
169
165
 
170
 
    def __init__(self, module_name, ignore_warnings=None):
 
166
    def __init__(self, module_name):
171
167
        super(ModuleAvailableFeature, self).__init__()
172
168
        self.module_name = module_name
173
 
        if ignore_warnings is None:
174
 
            ignore_warnings = ()
175
 
        self.ignore_warnings = ignore_warnings
176
169
 
177
170
    def _probe(self):
178
171
        sentinel = object()
179
172
        module = sys.modules.get(self.module_name, sentinel)
180
173
        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
 
174
            try:
 
175
                self._module = __import__(self.module_name, {}, {}, [''])
188
176
                return True
 
177
            except ImportError:
 
178
                return False
189
179
        else:
190
180
            self._module = module
191
181
            return True
215
205
        self.plugin_name = plugin_name
216
206
 
217
207
    def _probe(self):
218
 
        from breezy.plugin import get_loaded_plugin
219
 
        return (get_loaded_plugin(self.plugin_name) is not None)
 
208
        import breezy
 
209
        return self.plugin_name in breezy.global_state.plugins
220
210
 
221
211
    @property
222
212
    def plugin(self):
223
 
        from breezy.plugin import get_loaded_plugin
224
 
        return get_loaded_plugin(self.plugin_name)
 
213
        import breezy
 
214
        return breezy.global_state.plugins.get(self.plugin_name)
225
215
 
226
216
    def feature_name(self):
227
217
        return '%s plugin' % self.plugin_name
236
226
 
237
227
    def _probe(self):
238
228
        try:
239
 
            import ssl  # noqa: F401
 
229
            import ssl
240
230
            return True
241
231
        except ImportError:
242
232
            return False
256
246
            return True
257
247
        return False
258
248
 
259
 
 
260
249
ByteStringNamedFilesystem = _ByteStringNamedFilesystem()
261
250
 
262
251
 
268
257
            return True
269
258
        return False
270
259
 
271
 
 
272
260
UTF8Filesystem = _UTF8Filesystem()
273
261
 
274
262
 
284
272
            # We trigger SIGBREAK via a Console api so we need ctypes to
285
273
            # access the function
286
274
            try:
287
 
                import ctypes  # noqa: F401
 
275
                import ctypes
288
276
            except OSError:
289
277
                return False
290
278
        return True
307
295
            name = osutils.normpath(name)
308
296
            base, rel = osutils.split(name)
309
297
            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()))
 
298
            return (found_rel == rel
 
299
                    and os.path.isfile(name.upper())
 
300
                    and os.path.isfile(name.lower()))
313
301
        finally:
314
302
            os.close(fileno)
315
303
            os.remove(name)
317
305
    def feature_name(self):
318
306
        return "case-insensitive case-preserving filesystem"
319
307
 
320
 
 
321
308
CaseInsCasePresFilenameFeature = _CaseInsCasePresFilenameFeature()
322
309
 
323
310
 
340
327
        else:
341
328
            root = tests.TestCaseWithMemoryTransport.TEST_ROOT
342
329
        tdir = osutils.mkdtemp(prefix='case-sensitive-probe-', suffix='',
343
 
                               dir=root)
 
330
            dir=root)
344
331
        name_a = osutils.pathjoin(tdir, 'a')
345
332
        name_A = osutils.pathjoin(tdir, 'A')
346
333
        os.mkdir(name_a)
351
338
    def feature_name(self):
352
339
        return 'case-insensitive filesystem'
353
340
 
354
 
 
355
341
CaseInsensitiveFilesystemFeature = _CaseInsensitiveFilesystemFeature()
356
342
 
357
343
 
368
354
    def feature_name(self):
369
355
        return 'case-sensitive filesystem'
370
356
 
371
 
 
372
357
# new coding style is for feature instances to be lowercase
373
358
case_sensitive_filesystem_feature = _CaseSensitiveFilesystemFeature()
374
359
 
389
374
 
390
375
not_running_as_root = _NotRunningAsRoot()
391
376
 
392
 
# Apport uses deprecated imp module on python3.
393
 
apport = ModuleAvailableFeature(
394
 
    'apport.report',
395
 
    ignore_warnings=[DeprecationWarning, PendingDeprecationWarning])
 
377
apport = ModuleAvailableFeature('apport')
396
378
gpg = ModuleAvailableFeature('gpg')
397
379
lzma = ModuleAvailableFeature('lzma')
398
380
meliae = ModuleAvailableFeature('meliae.scanner')
400
382
pywintypes = ModuleAvailableFeature('pywintypes')
401
383
subunit = ModuleAvailableFeature('subunit')
402
384
testtools = ModuleAvailableFeature('testtools')
403
 
flake8 = ModuleAvailableFeature('flake8.api.legacy')
404
385
 
 
386
compiled_patiencediff_feature = ModuleAvailableFeature(
 
387
    'breezy._patiencediff_c')
405
388
lsprof_feature = ModuleAvailableFeature('breezy.lsprof')
406
 
pkg_resources_feature = ModuleAvailableFeature('pkg_resources')
407
 
 
408
 
pyinotify = ModuleAvailableFeature('pyinotify')
409
389
 
410
390
 
411
391
class _BackslashDirSeparatorFeature(Feature):
421
401
    def feature_name(self):
422
402
        return "Filesystem treats '\\' as a directory separator."
423
403
 
424
 
 
425
404
backslashdir_feature = _BackslashDirSeparatorFeature()
426
405
 
427
406
 
431
410
    def _probe(self):
432
411
        return os.name == 'posix' and hasattr(os, 'chown')
433
412
 
434
 
 
435
413
chown_feature = _ChownFeature()
436
414
 
437
415
 
493
471
    def _probe(self):
494
472
        try:
495
473
            proc = subprocess.Popen(['strace'],
496
 
                                    stderr=subprocess.PIPE,
497
 
                                    stdout=subprocess.PIPE)
 
474
                stderr=subprocess.PIPE,
 
475
                stdout=subprocess.PIPE)
498
476
            proc.communicate()
499
477
            return True
500
478
        except OSError as e:
501
 
            import errno
502
479
            if e.errno == errno.ENOENT:
503
480
                # strace is not installed
504
481
                return False
519
496
            return False
520
497
        try:
521
498
            proc = subprocess.Popen(['attrib', '.'], stdout=subprocess.PIPE)
522
 
        except OSError:
 
499
        except OSError as e:
523
500
            return False
524
501
        return (0 == proc.wait())
525
502
 
545
522
win32_feature = Win32Feature()
546
523
 
547
524
 
548
 
class _BackslashFilenameFeature(Feature):
549
 
    """Does the filesystem support backslashes in filenames?"""
550
 
 
551
 
    def _probe(self):
552
 
 
553
 
        try:
554
 
            fileno, name = tempfile.mkstemp(prefix='bzr\\prefix')
555
 
        except (IOError, OSError):
556
 
            return False
557
 
        else:
558
 
            try:
559
 
                os.stat(name)
560
 
            except (IOError, OSError):
561
 
                # mkstemp succeeded but the file wasn't actually created
562
 
                return False
563
 
            os.close(fileno)
564
 
            os.remove(name)
565
 
            return True
566
 
 
567
 
 
568
 
BackslashFilenameFeature = _BackslashFilenameFeature()
569
 
 
570
 
 
571
 
class PathFeature(Feature):
572
 
    """Feature testing whether a particular path exists."""
573
 
 
574
 
    def __init__(self, path):
575
 
        super(PathFeature, self).__init__()
576
 
        self.path = path
577
 
 
578
 
    def _probe(self):
579
 
        return os.path.exists(self.path)
 
525
class _ColorFeature(Feature):
 
526
 
 
527
    def _probe(self):
 
528
        from breezy._termcolor import allow_color
 
529
        return allow_color()
580
530
 
581
531
    def feature_name(self):
582
 
        return "%s exists" % self.path
 
532
        return "Terminal supports color."
 
533
 
 
534
ColorFeature = _ColorFeature()