/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/__init__.py

  • Committer: Jelmer Vernooij
  • Date: 2011-08-02 09:07:04 UTC
  • mfrom: (6047 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6050.
  • Revision ID: jelmer@samba.org-20110802090704-54mg7tjsbs2q12se
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
    memory,
89
89
    pathfilter,
90
90
    )
 
91
from bzrlib.symbol_versioning import (
 
92
    deprecated_function,
 
93
    deprecated_in,
 
94
    )
91
95
from bzrlib.tests import (
92
96
    test_server,
93
97
    TestUtil,
1157
1161
 
1158
1162
    def permit_dir(self, name):
1159
1163
        """Permit a directory to be used by this test. See permit_url."""
1160
 
        name_transport = _mod_transport.get_transport(name)
 
1164
        name_transport = _mod_transport.get_transport_from_path(name)
1161
1165
        self.permit_url(name)
1162
1166
        self.permit_url(name_transport.base)
1163
1167
 
1242
1246
        self.addCleanup(transport_server.stop_server)
1243
1247
        # Obtain a real transport because if the server supplies a password, it
1244
1248
        # will be hidden from the base on the client side.
1245
 
        t = _mod_transport.get_transport(transport_server.get_url())
 
1249
        t = _mod_transport.get_transport_from_url(transport_server.get_url())
1246
1250
        # Some transport servers effectively chroot the backing transport;
1247
1251
        # others like SFTPServer don't - users of the transport can walk up the
1248
1252
        # transport to read the entire backing transport. This wouldn't matter
1724
1728
    def overrideAttr(self, obj, attr_name, new=_unitialized_attr):
1725
1729
        """Overrides an object attribute restoring it after the test.
1726
1730
 
 
1731
        :note: This should be used with discretion; you should think about
 
1732
        whether it's better to make the code testable without monkey-patching.
 
1733
 
1727
1734
        :param obj: The object that will be mutated.
1728
1735
 
1729
1736
        :param attr_name: The attribute name we want to preserve/override in
1754
1761
        self.addCleanup(osutils.set_or_unset_env, name, value)
1755
1762
        return value
1756
1763
 
 
1764
    def recordCalls(self, obj, attr_name):
 
1765
        """Monkeypatch in a wrapper that will record calls.
 
1766
 
 
1767
        The monkeypatch is automatically removed when the test concludes.
 
1768
 
 
1769
        :param obj: The namespace holding the reference to be replaced;
 
1770
            typically a module, class, or object.
 
1771
        :param attr_name: A string for the name of the attribute to 
 
1772
            patch.
 
1773
        :returns: A list that will be extended with one item every time the
 
1774
            function is called, with a tuple of (args, kwargs).
 
1775
        """
 
1776
        calls = []
 
1777
 
 
1778
        def decorator(*args, **kwargs):
 
1779
            calls.append((args, kwargs))
 
1780
            return orig(*args, **kwargs)
 
1781
        orig = self.overrideAttr(obj, attr_name, decorator)
 
1782
        return calls
 
1783
 
1757
1784
    def _cleanEnvironment(self):
1758
1785
        for name, value in isolated_environ.iteritems():
1759
1786
            self.overrideEnv(name, value)
2360
2387
 
2361
2388
        :param relpath: a path relative to the base url.
2362
2389
        """
2363
 
        t = _mod_transport.get_transport(self.get_url(relpath))
 
2390
        t = _mod_transport.get_transport_from_url(self.get_url(relpath))
2364
2391
        self.assertFalse(t.is_readonly())
2365
2392
        return t
2366
2393
 
2591
2618
            backing_server = self.get_server()
2592
2619
        smart_server = test_server.SmartTCPServer_for_testing()
2593
2620
        self.start_server(smart_server, backing_server)
2594
 
        remote_transport = _mod_transport.get_transport(smart_server.get_url()
 
2621
        remote_transport = _mod_transport.get_transport_from_url(smart_server.get_url()
2595
2622
                                                   ).clone(path)
2596
2623
        return remote_transport
2597
2624
 
2614
2641
    def setUp(self):
2615
2642
        super(TestCaseWithMemoryTransport, self).setUp()
2616
2643
        # Ensure that ConnectedTransport doesn't leak sockets
2617
 
        def get_transport_with_cleanup(*args, **kwargs):
2618
 
            t = orig_get_transport(*args, **kwargs)
 
2644
        def get_transport_from_url_with_cleanup(*args, **kwargs):
 
2645
            t = orig_get_transport_from_url(*args, **kwargs)
2619
2646
            if isinstance(t, _mod_transport.ConnectedTransport):
2620
2647
                self.addCleanup(t.disconnect)
2621
2648
            return t
2622
2649
 
2623
 
        orig_get_transport = self.overrideAttr(_mod_transport, 'get_transport',
2624
 
                                               get_transport_with_cleanup)
 
2650
        orig_get_transport_from_url = self.overrideAttr(
 
2651
            _mod_transport, 'get_transport_from_url',
 
2652
            get_transport_from_url_with_cleanup)
2625
2653
        self._make_test_root()
2626
2654
        self.addCleanup(os.chdir, os.getcwdu())
2627
2655
        self.makeAndChdirToTestDir()
3886
3914
        'bzrlib.tests.test_export',
3887
3915
        'bzrlib.tests.test_export_pot',
3888
3916
        'bzrlib.tests.test_extract',
 
3917
        'bzrlib.tests.test_features',
3889
3918
        'bzrlib.tests.test_fetch',
3890
3919
        'bzrlib.tests.test_fixtures',
3891
3920
        'bzrlib.tests.test_fifo_cache',
4287
4316
        the module is available.
4288
4317
    """
4289
4318
 
 
4319
    from bzrlib.tests.features import ModuleAvailableFeature
4290
4320
    py_module = pyutils.get_named_object(py_module_name)
4291
4321
    scenarios = [
4292
4322
        ('python', {'module': py_module}),
4333
4363
                         % (os.path.basename(dirname), printable_e))
4334
4364
 
4335
4365
 
4336
 
class Feature(object):
4337
 
    """An operating system Feature."""
4338
 
 
4339
 
    def __init__(self):
4340
 
        self._available = None
4341
 
 
4342
 
    def available(self):
4343
 
        """Is the feature available?
4344
 
 
4345
 
        :return: True if the feature is available.
4346
 
        """
4347
 
        if self._available is None:
4348
 
            self._available = self._probe()
4349
 
        return self._available
4350
 
 
4351
 
    def _probe(self):
4352
 
        """Implement this method in concrete features.
4353
 
 
4354
 
        :return: True if the feature is available.
4355
 
        """
4356
 
        raise NotImplementedError
4357
 
 
4358
 
    def __str__(self):
4359
 
        if getattr(self, 'feature_name', None):
4360
 
            return self.feature_name()
4361
 
        return self.__class__.__name__
4362
 
 
4363
 
 
4364
 
class _SymlinkFeature(Feature):
4365
 
 
4366
 
    def _probe(self):
4367
 
        return osutils.has_symlinks()
4368
 
 
4369
 
    def feature_name(self):
4370
 
        return 'symlinks'
4371
 
 
4372
 
SymlinkFeature = _SymlinkFeature()
4373
 
 
4374
 
 
4375
 
class _HardlinkFeature(Feature):
4376
 
 
4377
 
    def _probe(self):
4378
 
        return osutils.has_hardlinks()
4379
 
 
4380
 
    def feature_name(self):
4381
 
        return 'hardlinks'
4382
 
 
4383
 
HardlinkFeature = _HardlinkFeature()
4384
 
 
4385
 
 
4386
 
class _OsFifoFeature(Feature):
4387
 
 
4388
 
    def _probe(self):
4389
 
        return getattr(os, 'mkfifo', None)
4390
 
 
4391
 
    def feature_name(self):
4392
 
        return 'filesystem fifos'
4393
 
 
4394
 
OsFifoFeature = _OsFifoFeature()
4395
 
 
4396
 
 
4397
 
class _UnicodeFilenameFeature(Feature):
4398
 
    """Does the filesystem support Unicode filenames?"""
4399
 
 
4400
 
    def _probe(self):
4401
 
        try:
4402
 
            # Check for character combinations unlikely to be covered by any
4403
 
            # single non-unicode encoding. We use the characters
4404
 
            # - greek small letter alpha (U+03B1) and
4405
 
            # - braille pattern dots-123456 (U+283F).
4406
 
            os.stat(u'\u03b1\u283f')
4407
 
        except UnicodeEncodeError:
4408
 
            return False
4409
 
        except (IOError, OSError):
4410
 
            # The filesystem allows the Unicode filename but the file doesn't
4411
 
            # exist.
4412
 
            return True
4413
 
        else:
4414
 
            # The filesystem allows the Unicode filename and the file exists,
4415
 
            # for some reason.
4416
 
            return True
4417
 
 
4418
 
UnicodeFilenameFeature = _UnicodeFilenameFeature()
4419
 
 
4420
 
 
4421
 
class _CompatabilityThunkFeature(Feature):
4422
 
    """This feature is just a thunk to another feature.
4423
 
 
4424
 
    It issues a deprecation warning if it is accessed, to let you know that you
4425
 
    should really use a different feature.
4426
 
    """
4427
 
 
4428
 
    def __init__(self, dep_version, module, name,
4429
 
                 replacement_name, replacement_module=None):
4430
 
        super(_CompatabilityThunkFeature, self).__init__()
4431
 
        self._module = module
4432
 
        if replacement_module is None:
4433
 
            replacement_module = module
4434
 
        self._replacement_module = replacement_module
4435
 
        self._name = name
4436
 
        self._replacement_name = replacement_name
4437
 
        self._dep_version = dep_version
4438
 
        self._feature = None
4439
 
 
4440
 
    def _ensure(self):
4441
 
        if self._feature is None:
4442
 
            depr_msg = self._dep_version % ('%s.%s'
4443
 
                                            % (self._module, self._name))
4444
 
            use_msg = ' Use %s.%s instead.' % (self._replacement_module,
4445
 
                                               self._replacement_name)
4446
 
            symbol_versioning.warn(depr_msg + use_msg, DeprecationWarning)
4447
 
            # Import the new feature and use it as a replacement for the
4448
 
            # deprecated one.
4449
 
            self._feature = pyutils.get_named_object(
4450
 
                self._replacement_module, self._replacement_name)
4451
 
 
4452
 
    def _probe(self):
4453
 
        self._ensure()
4454
 
        return self._feature._probe()
4455
 
 
4456
 
 
4457
 
class ModuleAvailableFeature(Feature):
4458
 
    """This is a feature than describes a module we want to be available.
4459
 
 
4460
 
    Declare the name of the module in __init__(), and then after probing, the
4461
 
    module will be available as 'self.module'.
4462
 
 
4463
 
    :ivar module: The module if it is available, else None.
4464
 
    """
4465
 
 
4466
 
    def __init__(self, module_name):
4467
 
        super(ModuleAvailableFeature, self).__init__()
4468
 
        self.module_name = module_name
4469
 
 
4470
 
    def _probe(self):
4471
 
        try:
4472
 
            self._module = __import__(self.module_name, {}, {}, [''])
4473
 
            return True
4474
 
        except ImportError:
4475
 
            return False
4476
 
 
4477
 
    @property
4478
 
    def module(self):
4479
 
        if self.available(): # Make sure the probe has been done
4480
 
            return self._module
4481
 
        return None
4482
 
 
4483
 
    def feature_name(self):
4484
 
        return self.module_name
4485
 
 
4486
 
 
4487
4366
def probe_unicode_in_user_encoding():
4488
4367
    """Try to encode several unicode strings to use in unicode-aware tests.
4489
4368
    Return first successfull match.
4517
4396
    return None
4518
4397
 
4519
4398
 
4520
 
class _HTTPSServerFeature(Feature):
4521
 
    """Some tests want an https Server, check if one is available.
4522
 
 
4523
 
    Right now, the only way this is available is under python2.6 which provides
4524
 
    an ssl module.
4525
 
    """
4526
 
 
4527
 
    def _probe(self):
4528
 
        try:
4529
 
            import ssl
4530
 
            return True
4531
 
        except ImportError:
4532
 
            return False
4533
 
 
4534
 
    def feature_name(self):
4535
 
        return 'HTTPSServer'
4536
 
 
4537
 
 
4538
 
HTTPSServerFeature = _HTTPSServerFeature()
4539
 
 
4540
 
 
4541
 
class _UnicodeFilename(Feature):
4542
 
    """Does the filesystem support Unicode filenames?"""
4543
 
 
4544
 
    def _probe(self):
4545
 
        try:
4546
 
            os.stat(u'\u03b1')
4547
 
        except UnicodeEncodeError:
4548
 
            return False
4549
 
        except (IOError, OSError):
4550
 
            # The filesystem allows the Unicode filename but the file doesn't
4551
 
            # exist.
4552
 
            return True
4553
 
        else:
4554
 
            # The filesystem allows the Unicode filename and the file exists,
4555
 
            # for some reason.
4556
 
            return True
4557
 
 
4558
 
UnicodeFilename = _UnicodeFilename()
4559
 
 
4560
 
 
4561
 
class _ByteStringNamedFilesystem(Feature):
4562
 
    """Is the filesystem based on bytes?"""
4563
 
 
4564
 
    def _probe(self):
4565
 
        if os.name == "posix":
4566
 
            return True
4567
 
        return False
4568
 
 
4569
 
ByteStringNamedFilesystem = _ByteStringNamedFilesystem()
4570
 
 
4571
 
 
4572
 
class _UTF8Filesystem(Feature):
4573
 
    """Is the filesystem UTF-8?"""
4574
 
 
4575
 
    def _probe(self):
4576
 
        if osutils._fs_enc.upper() in ('UTF-8', 'UTF8'):
4577
 
            return True
4578
 
        return False
4579
 
 
4580
 
UTF8Filesystem = _UTF8Filesystem()
4581
 
 
4582
 
 
4583
 
class _BreakinFeature(Feature):
4584
 
    """Does this platform support the breakin feature?"""
4585
 
 
4586
 
    def _probe(self):
4587
 
        from bzrlib import breakin
4588
 
        if breakin.determine_signal() is None:
4589
 
            return False
4590
 
        if sys.platform == 'win32':
4591
 
            # Windows doesn't have os.kill, and we catch the SIGBREAK signal.
4592
 
            # We trigger SIGBREAK via a Console api so we need ctypes to
4593
 
            # access the function
4594
 
            try:
4595
 
                import ctypes
4596
 
            except OSError:
4597
 
                return False
4598
 
        return True
4599
 
 
4600
 
    def feature_name(self):
4601
 
        return "SIGQUIT or SIGBREAK w/ctypes on win32"
4602
 
 
4603
 
 
4604
 
BreakinFeature = _BreakinFeature()
4605
 
 
4606
 
 
4607
 
class _CaseInsCasePresFilenameFeature(Feature):
4608
 
    """Is the file-system case insensitive, but case-preserving?"""
4609
 
 
4610
 
    def _probe(self):
4611
 
        fileno, name = tempfile.mkstemp(prefix='MixedCase')
4612
 
        try:
4613
 
            # first check truly case-preserving for created files, then check
4614
 
            # case insensitive when opening existing files.
4615
 
            name = osutils.normpath(name)
4616
 
            base, rel = osutils.split(name)
4617
 
            found_rel = osutils.canonical_relpath(base, name)
4618
 
            return (found_rel == rel
4619
 
                    and os.path.isfile(name.upper())
4620
 
                    and os.path.isfile(name.lower()))
4621
 
        finally:
4622
 
            os.close(fileno)
4623
 
            os.remove(name)
4624
 
 
4625
 
    def feature_name(self):
4626
 
        return "case-insensitive case-preserving filesystem"
4627
 
 
4628
 
CaseInsCasePresFilenameFeature = _CaseInsCasePresFilenameFeature()
4629
 
 
4630
 
 
4631
 
class _CaseInsensitiveFilesystemFeature(Feature):
4632
 
    """Check if underlying filesystem is case-insensitive but *not* case
4633
 
    preserving.
4634
 
    """
4635
 
    # Note that on Windows, Cygwin, MacOS etc, the file-systems are far
4636
 
    # more likely to be case preserving, so this case is rare.
4637
 
 
4638
 
    def _probe(self):
4639
 
        if CaseInsCasePresFilenameFeature.available():
4640
 
            return False
4641
 
 
4642
 
        if TestCaseWithMemoryTransport.TEST_ROOT is None:
4643
 
            root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
4644
 
            TestCaseWithMemoryTransport.TEST_ROOT = root
4645
 
        else:
4646
 
            root = TestCaseWithMemoryTransport.TEST_ROOT
4647
 
        tdir = osutils.mkdtemp(prefix='case-sensitive-probe-', suffix='',
4648
 
            dir=root)
4649
 
        name_a = osutils.pathjoin(tdir, 'a')
4650
 
        name_A = osutils.pathjoin(tdir, 'A')
4651
 
        os.mkdir(name_a)
4652
 
        result = osutils.isdir(name_A)
4653
 
        _rmtree_temp_dir(tdir)
4654
 
        return result
4655
 
 
4656
 
    def feature_name(self):
4657
 
        return 'case-insensitive filesystem'
4658
 
 
4659
 
CaseInsensitiveFilesystemFeature = _CaseInsensitiveFilesystemFeature()
4660
 
 
4661
 
 
4662
 
class _CaseSensitiveFilesystemFeature(Feature):
4663
 
 
4664
 
    def _probe(self):
4665
 
        if CaseInsCasePresFilenameFeature.available():
4666
 
            return False
4667
 
        elif CaseInsensitiveFilesystemFeature.available():
4668
 
            return False
4669
 
        else:
4670
 
            return True
4671
 
 
4672
 
    def feature_name(self):
4673
 
        return 'case-sensitive filesystem'
4674
 
 
4675
 
# new coding style is for feature instances to be lowercase
4676
 
case_sensitive_filesystem_feature = _CaseSensitiveFilesystemFeature()
4677
 
 
4678
 
 
4679
4399
# Only define SubUnitBzrRunner if subunit is available.
4680
4400
try:
4681
4401
    from subunit import TestProtocolClient
4699
4419
except ImportError:
4700
4420
    pass
4701
4421
 
4702
 
class _PosixPermissionsFeature(Feature):
4703
 
 
4704
 
    def _probe(self):
4705
 
        def has_perms():
4706
 
            # create temporary file and check if specified perms are maintained.
4707
 
            import tempfile
4708
 
 
4709
 
            write_perms = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
4710
 
            f = tempfile.mkstemp(prefix='bzr_perms_chk_')
4711
 
            fd, name = f
4712
 
            os.close(fd)
4713
 
            os.chmod(name, write_perms)
4714
 
 
4715
 
            read_perms = os.stat(name).st_mode & 0777
4716
 
            os.unlink(name)
4717
 
            return (write_perms == read_perms)
4718
 
 
4719
 
        return (os.name == 'posix') and has_perms()
4720
 
 
4721
 
    def feature_name(self):
4722
 
        return 'POSIX permissions support'
4723
 
 
4724
 
posix_permissions_feature = _PosixPermissionsFeature()
 
4422
 
 
4423
@deprecated_function(deprecated_in((2, 5, 0)))
 
4424
def ModuleAvailableFeature(name):
 
4425
    from bzrlib.tests import features
 
4426
    return features.ModuleAvailableFeature(name)
 
4427