~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Martin Pool
  • Date: 2006-02-01 12:24:35 UTC
  • mfrom: (1534.4.32 branch-formats)
  • mto: This revision was merged to the branch mainline in revision 1553.
  • Revision ID: mbp@sourcefrog.net-20060201122435-53f3efb1b5749fe1
[merge] branch-formats branch, and reconcile changes

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()
484
497
        if stdin is None:
485
498
            stdin = StringIO("")
486
499
        if stdout is None:
487
 
            if hasattr(self, "_log_file"):
 
500
            if getattr(self, "_log_file", None) is not None:
488
501
                stdout = self._log_file
489
502
            else:
490
503
                stdout = StringIO()
491
504
        if stderr is None:
492
 
            if hasattr(self, "_log_file"):
 
505
            if getattr(self, "_log_file", None is not None):
493
506
                stderr = self._log_file
494
507
            else:
495
508
                stderr = StringIO()
621
634
        self.assertEqualDiff(content, open(path, 'r').read())
622
635
 
623
636
 
 
637
class TestCaseWithTransport(TestCaseInTempDir):
 
638
    """A test case that provides get_url and get_readonly_url facilities.
 
639
 
 
640
    These back onto two transport servers, one for readonly access and one for
 
641
    read write access.
 
642
 
 
643
    If no explicit class is provided for readonly access, a
 
644
    ReadonlyTransportDecorator is used instead which allows the use of non disk
 
645
    based read write transports.
 
646
 
 
647
    If an explicit class is provided for readonly access, that server and the 
 
648
    readwrite one must both define get_url() as resolving to os.getcwd().
 
649
    """
 
650
 
 
651
    def __init__(self, methodName='testMethod'):
 
652
        super(TestCaseWithTransport, self).__init__(methodName)
 
653
        self.__readonly_server = None
 
654
        self.__server = None
 
655
        self.transport_server = default_transport
 
656
        self.transport_readonly_server = None
 
657
 
 
658
    def get_readonly_url(self, relpath=None):
 
659
        """Get a URL for the readonly transport.
 
660
 
 
661
        This will either be backed by '.' or a decorator to the transport 
 
662
        used by self.get_url()
 
663
        relpath provides for clients to get a path relative to the base url.
 
664
        These should only be downwards relative, not upwards.
 
665
        """
 
666
        if self.__readonly_server is None:
 
667
            if self.transport_readonly_server is None:
 
668
                # readonly decorator requested
 
669
                # bring up the server
 
670
                self.get_url()
 
671
                self.__readonly_server = ReadonlyServer()
 
672
                self.__readonly_server.setUp(self.__server)
 
673
            else:
 
674
                self.__readonly_server = self.transport_readonly_server()
 
675
                self.__readonly_server.setUp()
 
676
            self.addCleanup(self.__readonly_server.tearDown)
 
677
        base = self.__readonly_server.get_url()
 
678
        if relpath is not None:
 
679
            if not base.endswith('/'):
 
680
                base = base + '/'
 
681
            base = base + relpath
 
682
        return base
 
683
 
 
684
    def get_url(self, relpath=None):
 
685
        """Get a URL for the readwrite transport.
 
686
 
 
687
        This will either be backed by '.' or to an equivalent non-file based
 
688
        facility.
 
689
        relpath provides for clients to get a path relative to the base url.
 
690
        These should only be downwards relative, not upwards.
 
691
        """
 
692
        if self.__server is None:
 
693
            self.__server = self.transport_server()
 
694
            self.__server.setUp()
 
695
            self.addCleanup(self.__server.tearDown)
 
696
        base = self.__server.get_url()
 
697
        if relpath is not None and relpath != '.':
 
698
            if not base.endswith('/'):
 
699
                base = base + '/'
 
700
            base = base + relpath
 
701
        return base
 
702
 
 
703
    def make_branch(self, relpath):
 
704
        """Create a branch on the transport at relpath."""
 
705
        try:
 
706
            url = self.get_url(relpath)
 
707
            segments = relpath.split('/')
 
708
            if segments and segments[-1] not in ('', '.'):
 
709
                parent = self.get_url('/'.join(segments[:-1]))
 
710
                t = bzrlib.transport.get_transport(parent)
 
711
                try:
 
712
                    t.mkdir(segments[-1])
 
713
                except FileExists:
 
714
                    pass
 
715
            return bzrlib.branch.Branch.create(url)
 
716
        except UninitializableFormat:
 
717
            raise TestSkipped("Format %s is not initializable.")
 
718
 
 
719
    def make_branch_and_tree(self, relpath):
 
720
        """Create a branch on the transport and a tree locally.
 
721
 
 
722
        Returns the tree.
 
723
        """
 
724
        b = self.make_branch(relpath)
 
725
        return WorkingTree.create(b, relpath)
 
726
 
 
727
 
 
728
class ChrootedTestCase(TestCaseWithTransport):
 
729
    """A support class that provides readonly urls outside the local namespace.
 
730
 
 
731
    This is done by checking if self.transport_server is a MemoryServer. if it
 
732
    is then we are chrooted already, if it is not then an HttpServer is used
 
733
    for readonly urls.
 
734
 
 
735
    TODO RBC 20060127: make this an option to TestCaseWithTransport so it can
 
736
                       be used without needed to redo it when a different 
 
737
                       subclass is in use ?
 
738
    """
 
739
 
 
740
    def setUp(self):
 
741
        super(ChrootedTestCase, self).setUp()
 
742
        if not self.transport_server == bzrlib.transport.memory.MemoryServer:
 
743
            self.transport_readonly_server = bzrlib.transport.http.HttpServer
 
744
 
 
745
 
624
746
def filter_suite_by_re(suite, pattern):
625
747
    result = TestSuite()
626
748
    filter_re = re.compile(pattern)
631
753
 
632
754
 
633
755
def run_suite(suite, name='test', verbose=False, pattern=".*",
634
 
              stop_on_failure=False, keep_output=False):
 
756
              stop_on_failure=False, keep_output=False,
 
757
              transport=None):
635
758
    TestCaseInTempDir._TEST_NAME = name
636
759
    if verbose:
637
760
        verbosity = 2
656
779
 
657
780
 
658
781
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
659
 
             keep_output=False):
 
782
             keep_output=False,
 
783
             transport=None):
660
784
    """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)
 
785
    global default_transport
 
786
    if transport is None:
 
787
        transport = default_transport
 
788
    old_transport = default_transport
 
789
    default_transport = transport
 
790
    suite = test_suite()
 
791
    try:
 
792
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
 
793
                     stop_on_failure=stop_on_failure, keep_output=keep_output,
 
794
                     transport=transport)
 
795
    finally:
 
796
        default_transport = old_transport
 
797
 
663
798
 
664
799
 
665
800
def test_suite():
703
838
                   'bzrlib.tests.test_parent',
704
839
                   'bzrlib.tests.test_permissions',
705
840
                   'bzrlib.tests.test_plugins',
706
 
                   'bzrlib.tests.test_remove',
707
841
                   'bzrlib.tests.test_revision',
708
842
                   'bzrlib.tests.test_revisionnamespaces',
709
843
                   'bzrlib.tests.test_revprops',
715
849
                   'bzrlib.tests.test_sftp_transport',
716
850
                   'bzrlib.tests.test_smart_add',
717
851
                   'bzrlib.tests.test_source',
718
 
                   'bzrlib.tests.test_status',
719
852
                   'bzrlib.tests.test_store',
720
853
                   'bzrlib.tests.test_symbol_versioning',
721
854
                   'bzrlib.tests.test_testament',
747
880
    loader = TestLoader()
748
881
    from bzrlib.transport import TransportTestProviderAdapter
749
882
    adapter = TransportTestProviderAdapter()
750
 
    for mod_name in test_transport_implementations:
751
 
        mod = _load_module_by_name(mod_name)
752
 
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
753
 
            suite.addTests(adapter.adapt(test))
 
883
    adapt_modules(test_transport_implementations, adapter, loader, suite)
754
884
    for mod_name in testmod_names:
755
885
        mod = _load_module_by_name(mod_name)
756
886
        suite.addTest(loader.loadTestsFromModule(mod))
761
891
    for m in (MODULES_TO_DOCTEST):
762
892
        suite.addTest(DocTestSuite(m))
763
893
    for name, plugin in bzrlib.plugin.all_plugins().items():
764
 
        if hasattr(plugin, 'test_suite'):
 
894
        if getattr(plugin, 'test_suite', None) is not None:
765
895
            suite.addTest(plugin.test_suite())
766
896
    return suite
767
897
 
768
898
 
 
899
def adapt_modules(mods_list, adapter, loader, suite):
 
900
    """Adapt the modules in mods_list using adapter and add to suite."""
 
901
    for mod_name in mods_list:
 
902
        mod = _load_module_by_name(mod_name)
 
903
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
 
904
            suite.addTests(adapter.adapt(test))
 
905
 
 
906
 
769
907
def _load_module_by_name(mod_name):
770
908
    parts = mod_name.split('.')
771
909
    module = __import__(mod_name)