~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

Merge from bzr.ab

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 
38
38
import bzrlib.branch
39
39
import bzrlib.commands
40
 
from bzrlib.errors import BzrError
 
40
from bzrlib.errors import (BzrError,
 
41
                           FileExists,
 
42
                           UninitializableFormat,
 
43
                           )
41
44
import bzrlib.inventory
42
45
import bzrlib.iterablefile
43
46
import bzrlib.merge3
47
50
import bzrlib.store
48
51
import bzrlib.trace
49
52
from bzrlib.transport import urlescape
 
53
import bzrlib.transport
 
54
from bzrlib.transport.local import LocalRelpathServer
 
55
from bzrlib.transport.readonly import ReadonlyServer
50
56
from bzrlib.trace import mutter
51
57
from bzrlib.tests.TestUtil import TestLoader, TestSuite
52
58
from bzrlib.tests.treeshape import build_tree_contents
 
59
from bzrlib.workingtree import WorkingTree
 
60
 
 
61
default_transport = LocalRelpathServer
53
62
 
54
63
MODULES_TO_TEST = []
55
64
MODULES_TO_DOCTEST = [
71
80
    """
72
81
    import bzrlib.doc
73
82
    import bzrlib.tests.blackbox
 
83
    import bzrlib.tests.branch_implementations
74
84
    return [
75
85
            bzrlib.doc,
76
 
            bzrlib.tests.blackbox
 
86
            bzrlib.tests.branch_implementations,
77
87
            ]
78
88
 
79
89
 
158
168
        for test, err in errors:
159
169
            self.stream.writeln(self.separator1)
160
170
            self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
161
 
            if hasattr(test, '_get_log'):
 
171
            if getattr(test, '_get_log', None) is not None:
162
172
                print >>self.stream
163
173
                print >>self.stream, \
164
174
                        ('vvvv[log from %s]' % test.id()).ljust(78,'-')
224
234
    _log_file_name = None
225
235
    _log_contents = ''
226
236
 
 
237
    def __init__(self, methodName='testMethod'):
 
238
        super(TestCase, self).__init__(methodName)
 
239
        self._cleanups = []
 
240
 
227
241
    def setUp(self):
228
242
        unittest.TestCase.setUp(self)
229
 
        self._cleanups = []
230
243
        self._cleanEnvironment()
231
244
        bzrlib.trace.disable_default_logging()
232
245
        self._startLogFile()
306
319
        fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
307
320
        encoder, decoder, stream_reader, stream_writer = codecs.lookup('UTF-8')
308
321
        self._log_file = stream_writer(os.fdopen(fileno, 'w+'))
309
 
        bzrlib.trace.enable_test_log(self._log_file)
 
322
        self._log_nonce = bzrlib.trace.enable_test_log(self._log_file)
310
323
        self._log_file_name = name
311
324
        self.addCleanup(self._finishLogFile)
312
325
 
315
328
 
316
329
        Read contents into memory, close, and delete.
317
330
        """
318
 
        bzrlib.trace.disable_test_log()
 
331
        bzrlib.trace.disable_test_log(self._log_nonce)
319
332
        self._log_file.seek(0)
320
333
        self._log_contents = self._log_file.read()
321
334
        self._log_file.close()
425
438
        handler.setLevel(logging.INFO)
426
439
        logger = logging.getLogger('')
427
440
        logger.addHandler(handler)
 
441
        if isinstance(argv, basestring):
 
442
            argv = '--no-defaults ' + argv
 
443
        else:
 
444
            argv = ['--no-defaults'] + list(argv)
428
445
        try:
429
446
            result = self.apply_redirected(None, stdout, stderr,
430
447
                                           bzrlib.commands.run_bzr_catch_errors,
484
501
        if stdin is None:
485
502
            stdin = StringIO("")
486
503
        if stdout is None:
487
 
            if hasattr(self, "_log_file"):
 
504
            if getattr(self, "_log_file", None) is not None:
488
505
                stdout = self._log_file
489
506
            else:
490
507
                stdout = StringIO()
491
508
        if stderr is None:
492
 
            if hasattr(self, "_log_file"):
 
509
            if getattr(self, "_log_file", None is not None):
493
510
                stderr = self._log_file
494
511
            else:
495
512
                stderr = StringIO()
621
638
        self.assertEqualDiff(content, open(path, 'r').read())
622
639
 
623
640
 
 
641
class TestCaseWithTransport(TestCaseInTempDir):
 
642
    """A test case that provides get_url and get_readonly_url facilities.
 
643
 
 
644
    These back onto two transport servers, one for readonly access and one for
 
645
    read write access.
 
646
 
 
647
    If no explicit class is provided for readonly access, a
 
648
    ReadonlyTransportDecorator is used instead which allows the use of non disk
 
649
    based read write transports.
 
650
 
 
651
    If an explicit class is provided for readonly access, that server and the 
 
652
    readwrite one must both define get_url() as resolving to os.getcwd().
 
653
    """
 
654
 
 
655
    def __init__(self, methodName='testMethod'):
 
656
        super(TestCaseWithTransport, self).__init__(methodName)
 
657
        self.__readonly_server = None
 
658
        self.__server = None
 
659
        self.transport_server = default_transport
 
660
        self.transport_readonly_server = None
 
661
 
 
662
    def get_readonly_url(self, relpath=None):
 
663
        """Get a URL for the readonly transport.
 
664
 
 
665
        This will either be backed by '.' or a decorator to the transport 
 
666
        used by self.get_url()
 
667
        relpath provides for clients to get a path relative to the base url.
 
668
        These should only be downwards relative, not upwards.
 
669
        """
 
670
        if self.__readonly_server is None:
 
671
            if self.transport_readonly_server is None:
 
672
                # readonly decorator requested
 
673
                # bring up the server
 
674
                self.get_url()
 
675
                self.__readonly_server = ReadonlyServer()
 
676
                self.__readonly_server.setUp(self.__server)
 
677
            else:
 
678
                self.__readonly_server = self.transport_readonly_server()
 
679
                self.__readonly_server.setUp()
 
680
            self.addCleanup(self.__readonly_server.tearDown)
 
681
        base = self.__readonly_server.get_url()
 
682
        if relpath is not None:
 
683
            if not base.endswith('/'):
 
684
                base = base + '/'
 
685
            base = base + relpath
 
686
        return base
 
687
 
 
688
    def get_url(self, relpath=None):
 
689
        """Get a URL for the readwrite transport.
 
690
 
 
691
        This will either be backed by '.' or to an equivalent non-file based
 
692
        facility.
 
693
        relpath provides for clients to get a path relative to the base url.
 
694
        These should only be downwards relative, not upwards.
 
695
        """
 
696
        if self.__server is None:
 
697
            self.__server = self.transport_server()
 
698
            self.__server.setUp()
 
699
            self.addCleanup(self.__server.tearDown)
 
700
        base = self.__server.get_url()
 
701
        if relpath is not None and relpath != '.':
 
702
            if not base.endswith('/'):
 
703
                base = base + '/'
 
704
            base = base + relpath
 
705
        return base
 
706
 
 
707
    def make_branch(self, relpath):
 
708
        """Create a branch on the transport at relpath."""
 
709
        try:
 
710
            url = self.get_url(relpath)
 
711
            segments = relpath.split('/')
 
712
            if segments and segments[-1] not in ('', '.'):
 
713
                parent = self.get_url('/'.join(segments[:-1]))
 
714
                t = bzrlib.transport.get_transport(parent)
 
715
                try:
 
716
                    t.mkdir(segments[-1])
 
717
                except FileExists:
 
718
                    pass
 
719
            return bzrlib.branch.Branch.create(url)
 
720
        except UninitializableFormat:
 
721
            raise TestSkipped("Format %s is not initializable.")
 
722
 
 
723
    def make_branch_and_tree(self, relpath):
 
724
        """Create a branch on the transport and a tree locally.
 
725
 
 
726
        Returns the tree.
 
727
        """
 
728
        b = self.make_branch(relpath)
 
729
        return WorkingTree.create(b, relpath)
 
730
 
 
731
 
 
732
class ChrootedTestCase(TestCaseWithTransport):
 
733
    """A support class that provides readonly urls outside the local namespace.
 
734
 
 
735
    This is done by checking if self.transport_server is a MemoryServer. if it
 
736
    is then we are chrooted already, if it is not then an HttpServer is used
 
737
    for readonly urls.
 
738
 
 
739
    TODO RBC 20060127: make this an option to TestCaseWithTransport so it can
 
740
                       be used without needed to redo it when a different 
 
741
                       subclass is in use ?
 
742
    """
 
743
 
 
744
    def setUp(self):
 
745
        super(ChrootedTestCase, self).setUp()
 
746
        if not self.transport_server == bzrlib.transport.memory.MemoryServer:
 
747
            self.transport_readonly_server = bzrlib.transport.http.HttpServer
 
748
 
 
749
 
624
750
def filter_suite_by_re(suite, pattern):
625
751
    result = TestSuite()
626
752
    filter_re = re.compile(pattern)
631
757
 
632
758
 
633
759
def run_suite(suite, name='test', verbose=False, pattern=".*",
634
 
              stop_on_failure=False, keep_output=False):
 
760
              stop_on_failure=False, keep_output=False,
 
761
              transport=None):
635
762
    TestCaseInTempDir._TEST_NAME = name
636
763
    if verbose:
637
764
        verbosity = 2
656
783
 
657
784
 
658
785
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
659
 
             keep_output=False):
 
786
             keep_output=False,
 
787
             transport=None):
660
788
    """Run the whole test suite under the enhanced runner"""
661
 
    return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern,
662
 
                     stop_on_failure=stop_on_failure, keep_output=keep_output)
 
789
    global default_transport
 
790
    if transport is None:
 
791
        transport = default_transport
 
792
    old_transport = default_transport
 
793
    default_transport = transport
 
794
    suite = test_suite()
 
795
    try:
 
796
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
 
797
                     stop_on_failure=stop_on_failure, keep_output=keep_output,
 
798
                     transport=transport)
 
799
    finally:
 
800
        default_transport = old_transport
 
801
 
663
802
 
664
803
 
665
804
def test_suite():
703
842
                   'bzrlib.tests.test_parent',
704
843
                   'bzrlib.tests.test_permissions',
705
844
                   'bzrlib.tests.test_plugins',
706
 
                   'bzrlib.tests.test_remove',
707
845
                   'bzrlib.tests.test_revision',
708
846
                   'bzrlib.tests.test_revisionnamespaces',
709
847
                   'bzrlib.tests.test_revprops',
715
853
                   'bzrlib.tests.test_sftp_transport',
716
854
                   'bzrlib.tests.test_smart_add',
717
855
                   'bzrlib.tests.test_source',
718
 
                   'bzrlib.tests.test_status',
719
856
                   'bzrlib.tests.test_store',
720
857
                   'bzrlib.tests.test_symbol_versioning',
721
858
                   'bzrlib.tests.test_testament',
748
885
    loader = TestLoader()
749
886
    from bzrlib.transport import TransportTestProviderAdapter
750
887
    adapter = TransportTestProviderAdapter()
751
 
    for mod_name in test_transport_implementations:
752
 
        mod = _load_module_by_name(mod_name)
753
 
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
754
 
            suite.addTests(adapter.adapt(test))
 
888
    adapt_modules(test_transport_implementations, adapter, loader, suite)
755
889
    for mod_name in testmod_names:
756
890
        mod = _load_module_by_name(mod_name)
757
891
        suite.addTest(loader.loadTestsFromModule(mod))
762
896
    for m in (MODULES_TO_DOCTEST):
763
897
        suite.addTest(DocTestSuite(m))
764
898
    for name, plugin in bzrlib.plugin.all_plugins().items():
765
 
        if hasattr(plugin, 'test_suite'):
 
899
        if getattr(plugin, 'test_suite', None) is not None:
766
900
            suite.addTest(plugin.test_suite())
767
901
    return suite
768
902
 
769
903
 
 
904
def adapt_modules(mods_list, adapter, loader, suite):
 
905
    """Adapt the modules in mods_list using adapter and add to suite."""
 
906
    for mod_name in mods_list:
 
907
        mod = _load_module_by_name(mod_name)
 
908
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
 
909
            suite.addTests(adapter.adapt(test))
 
910
 
 
911
 
770
912
def _load_module_by_name(mod_name):
771
913
    parts = mod_name.split('.')
772
914
    module = __import__(mod_name)